Repository: visualvm/visualvm.src Branch: master Commit: 717c75744274 Files: 3699 Total size: 21.8 MB Directory structure: gitextract_zy0074e6/ ├── .github/ │ └── ISSUE_TEMPLATE/ │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── THIRDPARTYLICENSE ├── integrations/ │ ├── eclipse/ │ │ ├── org.eclipse.visualvm.launcher/ │ │ │ ├── .project │ │ │ ├── build.properties │ │ │ └── feature.xml │ │ ├── org.eclipse.visualvm.launcher.common/ │ │ │ ├── .classpath │ │ │ ├── .project │ │ │ ├── .settings/ │ │ │ │ └── org.eclipse.jdt.core.prefs │ │ │ ├── META-INF/ │ │ │ │ └── MANIFEST.MF │ │ │ ├── build.properties │ │ │ ├── plugin.xml │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── eclipse/ │ │ │ └── visualvm/ │ │ │ └── launcher/ │ │ │ ├── Activator.java │ │ │ ├── api/ │ │ │ │ └── VisualVMHelper.java │ │ │ ├── preferences/ │ │ │ │ ├── LocationPreferencePage.java │ │ │ │ ├── PreferenceConstants.java │ │ │ │ └── PreferenceInitializer.java │ │ │ └── resources/ │ │ │ ├── LauncherMessages.java │ │ │ ├── LauncherMessages.properties │ │ │ ├── PreferencesMessages.java │ │ │ └── PreferencesMessages.properties │ │ ├── org.eclipse.visualvm.launcher.java/ │ │ │ ├── .classpath │ │ │ ├── .project │ │ │ ├── .settings/ │ │ │ │ └── org.eclipse.jdt.core.prefs │ │ │ ├── META-INF/ │ │ │ │ └── MANIFEST.MF │ │ │ ├── build.properties │ │ │ ├── plugin.xml │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── eclipse/ │ │ │ └── visualvm/ │ │ │ └── launcher/ │ │ │ └── java/ │ │ │ ├── VisualVMAppletDelegate.java │ │ │ ├── VisualVMJUnitDelegate.java │ │ │ └── VisualVMJavaDelegate.java │ │ ├── org.eclipse.visualvm.launcher.pde/ │ │ │ ├── .classpath │ │ │ ├── .project │ │ │ ├── .settings/ │ │ │ │ └── org.eclipse.jdt.core.prefs │ │ │ ├── META-INF/ │ │ │ │ └── MANIFEST.MF │ │ │ ├── build.properties │ │ │ ├── plugin.xml │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── eclipse/ │ │ │ └── visualvm/ │ │ │ └── launcher/ │ │ │ └── pde/ │ │ │ ├── VisualVMJUnitPluginDelegate.java │ │ │ └── VisualVMPDEDelegate.java │ │ └── org.eclipse.visualvm.launcher.update/ │ │ ├── .project │ │ └── site.xml │ └── vscode/ │ ├── .eslintrc.js │ ├── .gitignore │ ├── .nvmrc │ ├── .vscode/ │ │ ├── launch.json │ │ ├── settings.json │ │ └── tasks.json │ ├── .vscodeignore │ ├── CHANGELOG.md │ ├── README.md │ ├── fixtures/ │ │ └── test projects/ │ │ └── demo/ │ │ ├── .gitignore │ │ ├── .mvn/ │ │ │ └── wrapper/ │ │ │ └── maven-wrapper.properties │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── README.md │ │ ├── lib/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── .gitkeep │ │ │ └── resources/ │ │ │ └── .gitkeep │ │ ├── micronaut-cli.yml │ │ ├── mvnw │ │ ├── mvnw.bat │ │ ├── oci/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── Application.java │ │ │ │ └── resources/ │ │ │ │ ├── application-oraclecloud.properties │ │ │ │ ├── bootstrap-oraclecloud.properties │ │ │ │ └── logback.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── OciTest.java │ │ └── pom.xml │ ├── package.json │ ├── src/ │ │ ├── commands.ts │ │ ├── download.ts │ │ ├── extension.ts │ │ ├── install.ts │ │ ├── jdk.ts │ │ ├── logUtils.ts │ │ ├── monitoredProcesses.ts │ │ ├── nodes.ts │ │ ├── parameters.ts │ │ ├── presets.ts │ │ ├── projectUtils.ts │ │ ├── runningProcesses.ts │ │ ├── test/ │ │ │ ├── README.md │ │ │ ├── runTest.ts │ │ │ └── suite/ │ │ │ ├── download.test.ts │ │ │ ├── extension.test.ts │ │ │ ├── index.ts │ │ │ ├── utils.ts │ │ │ └── visualvm.test.ts │ │ ├── view.ts │ │ ├── visualvm.ts │ │ └── vscodeUtils.ts │ ├── tsconfig.eslint.json │ ├── tsconfig.json │ └── webpack.config.js ├── plugins/ │ ├── btrace/ │ │ └── PROJECT_MOVED.txt │ ├── buffermonitor/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── buffermonitor/ │ │ ├── BufferMonitorView.java │ │ ├── BufferMonitorViewProvider.java │ │ ├── Bundle.properties │ │ └── Installer.java │ ├── build.xml │ ├── consumerentrypoints/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── netbeans/ │ │ └── modules/ │ │ └── consumerentrypoints/ │ │ └── resources/ │ │ ├── Bundle.properties │ │ ├── glassfish.xml │ │ └── layer.xml │ ├── consumervisualvm/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ ├── META-INF/ │ │ │ └── services/ │ │ │ └── org.openide.filesystems.FileSystem │ │ └── org/ │ │ └── netbeans/ │ │ └── modules/ │ │ └── consumervisualvm/ │ │ ├── DecoratedFileSystem.java │ │ ├── PluginInfoAccessor.java │ │ ├── api/ │ │ │ ├── ApplicationTypeAction.java │ │ │ ├── Bundle.properties │ │ │ └── PluginInfo.java │ │ ├── engine/ │ │ │ ├── Bundle.properties │ │ │ ├── FindComponentModules.java │ │ │ ├── FlashingIcon.java │ │ │ ├── ModulesActivator.java │ │ │ ├── ModulesInstaller.java │ │ │ └── RestartNotifier.java │ │ └── resources/ │ │ └── Bundle.properties │ ├── extapptypes/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── customtype/ │ │ ├── ApplicationType.java │ │ ├── ApplicationTypeFactory.java │ │ ├── ApplicationTypeManager.java │ │ ├── Bundle.properties │ │ ├── Installer.java │ │ ├── actions/ │ │ │ ├── EditApplicationTypeAction.java │ │ │ ├── NewApplicationTypeAction.java │ │ │ └── ValidationSupport.java │ │ ├── icons/ │ │ │ ├── FileImagePersistor.java │ │ │ ├── IconCache.java │ │ │ ├── IconResolver.java │ │ │ └── ImageUtils.java │ │ ├── layer.xml │ │ ├── options/ │ │ │ ├── ApplicationTypeOptionsCategory.java │ │ │ ├── ApplicationTypeOptionsPanel.form │ │ │ ├── ApplicationTypeOptionsPanel.java │ │ │ ├── ApplicationTypesOptionsPanelController.java │ │ │ └── Bundle.properties │ │ └── ui/ │ │ ├── ApplicationTypeForm.form │ │ ├── ApplicationTypeForm.java │ │ └── Bundle.properties │ ├── extapptypes.lib/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── customtype/ │ │ └── lib/ │ │ ├── Bundle.properties │ │ └── layer.xml │ ├── extensions/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── extensions/ │ │ ├── Bundle.properties │ │ ├── DiabloJvmJvmstatModelProvider.java │ │ ├── ExtendedJvmJvmstatModel.java │ │ ├── Installer.java │ │ └── SapJvmJvmstatModelProvider.java │ ├── glassfish/ │ │ ├── amx-api/ │ │ │ ├── DUAL_LICENSE.txt │ │ │ ├── build.xml │ │ │ ├── manifest.mf │ │ │ ├── nbproject/ │ │ │ │ ├── build-impl.xml │ │ │ │ ├── genfiles.properties │ │ │ │ ├── project.properties │ │ │ │ ├── project.xml │ │ │ │ └── suite.properties │ │ │ ├── release/ │ │ │ │ └── modules/ │ │ │ │ └── ext/ │ │ │ │ ├── amxapi.jar │ │ │ │ ├── j2ee.jar │ │ │ │ └── javaee.jar │ │ │ └── src/ │ │ │ └── com/ │ │ │ └── sun/ │ │ │ └── appserv/ │ │ │ └── management/ │ │ │ └── Bundle.properties │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── net/ │ │ └── java/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── glassfish/ │ │ ├── Bundle.properties │ │ ├── GlassFishApplicationType.java │ │ ├── GlassFishApplicationTypeFactory.java │ │ ├── GlassFishInstanceType.java │ │ ├── GlassFishNodeType.java │ │ ├── GlassFishOverviewPlugin.java │ │ ├── GlassFishOverviewPluginProvider.java │ │ ├── Installer.java │ │ ├── datasource/ │ │ │ ├── GlassFishApplication.java │ │ │ ├── GlassFishApplicationProvider.java │ │ │ ├── GlassFishDataSource.java │ │ │ ├── GlassFishDataSourceDescriptorProvider.java │ │ │ ├── GlassFishModel.java │ │ │ ├── GlassFishModelProvider.java │ │ │ ├── GlassFishServlet.java │ │ │ ├── GlassFishServletProvider.java │ │ │ └── GlassFishWebModule.java │ │ ├── dataview/ │ │ │ ├── AbstractStatsTableModel.java │ │ │ ├── Bundle.properties │ │ │ ├── GlassFishApplicationViewProvider.java │ │ │ ├── GlassFishServletViewProvider.java │ │ │ ├── GlassFishWebModuleViewProvider.java │ │ │ ├── HTTPServiceView.java │ │ │ ├── ServletTableModel.java │ │ │ ├── TransactionServiceView.java │ │ │ └── WSTableModel.java │ │ ├── jmx/ │ │ │ ├── AMXUtil.java │ │ │ ├── Bundle.properties │ │ │ ├── GFJmxModelFactory.java │ │ │ ├── JMXDetailsPanel.form │ │ │ ├── JMXDetailsPanel.java │ │ │ └── JMXUtil.java │ │ ├── ui/ │ │ │ ├── Bundle.properties │ │ │ ├── GenericModel.java │ │ │ ├── StatsTable.java │ │ │ └── Tachometer.java │ │ └── util/ │ │ └── Touple.java │ ├── graaljs/ │ │ ├── build.xml │ │ ├── external/ │ │ │ ├── asm-util-9.2-license.txt │ │ │ ├── binaries-list │ │ │ ├── icu4j-71.1-license.txt │ │ │ └── js-22.3.0-license.txt │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── graaljs/ │ │ └── Bundle.properties │ ├── jconsole/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ ├── com/ │ │ │ └── sun/ │ │ │ └── tools/ │ │ │ └── jconsole/ │ │ │ ├── JConsoleContext.java │ │ │ └── JConsolePlugin.java │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── jconsole/ │ │ ├── Bundle.properties │ │ ├── Install.java │ │ ├── JConsolePluginWrapper.java │ │ ├── JConsoleView.java │ │ ├── JConsoleViewProvider.java │ │ ├── JConsoleViewsSupport.java │ │ └── options/ │ │ ├── Bundle.properties │ │ ├── JConsoleCustomizer.java │ │ ├── JConsoleOptionsPanelController.java │ │ ├── JConsoleSettings.java │ │ └── PathController.java │ ├── jfr.streaming/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── jfr/ │ │ └── streaming/ │ │ ├── Bundle.properties │ │ ├── Installer.java │ │ ├── JFRStream.java │ │ ├── network/ │ │ │ ├── Bundle.properties │ │ │ ├── NetworkModel.java │ │ │ ├── NetworkViewComponent.java │ │ │ ├── NetworkViewPlugin.java │ │ │ └── NetworkViewPluginProvider.java │ │ └── threads/ │ │ ├── JFRThreadDataProvider.java │ │ └── ThreadMonitoringProvider.java │ ├── jolokia/ │ │ ├── build.xml │ │ ├── external/ │ │ │ ├── binaries-list │ │ │ ├── commons-codec-1.17.1-license.txt │ │ │ ├── commons-logging-1.3.4-license.txt │ │ │ ├── httpclient-4.5.14-license.txt │ │ │ ├── jackson-2.18.2-license.txt │ │ │ ├── jolokia-client-kubernetes-2.2.2-license.txt │ │ │ ├── kubernetes-client-6.13.4-license.txt │ │ │ ├── okhttp-3.12.12-license.txt │ │ │ ├── slf4j-api-2.0.13-license.txt │ │ │ ├── snakeyaml-2.2-license.txt │ │ │ └── snakeyaml-engine-2.7-license.txt │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── jolokia/ │ │ └── Bundle.properties │ ├── jsyntaxpane-lib/ │ │ ├── build.xml │ │ ├── external/ │ │ │ └── jsyntaxpane/ │ │ │ ├── APACHE-LICENSE-2.0.txt │ │ │ ├── CHANGELOG.txt │ │ │ ├── nbactions.xml │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── jsyntaxpane/ │ │ │ │ ├── CompoundUndoManager.java │ │ │ │ ├── DefaultLexer.java │ │ │ │ ├── DefaultSyntaxKit.java │ │ │ │ ├── Lexer.java │ │ │ │ ├── SyntaxDocument.java │ │ │ │ ├── SyntaxStyle.java │ │ │ │ ├── SyntaxStyles.java │ │ │ │ ├── SyntaxTester.form │ │ │ │ ├── SyntaxTester.java │ │ │ │ ├── SyntaxView.java │ │ │ │ ├── Token.java │ │ │ │ ├── TokenType.java │ │ │ │ ├── actions/ │ │ │ │ │ ├── ActionUtils.java │ │ │ │ │ ├── CaretMonitor.java │ │ │ │ │ ├── ComboCompletionAction.java │ │ │ │ │ ├── ComboCompletionDialog.form │ │ │ │ │ ├── ComboCompletionDialog.java │ │ │ │ │ ├── DeleteLinesAction.java │ │ │ │ │ ├── DuplicateLinesAction.java │ │ │ │ │ ├── FindReplaceActions.java │ │ │ │ │ ├── GotoLineAction.java │ │ │ │ │ ├── GotoLineDialog.form │ │ │ │ │ ├── GotoLineDialog.java │ │ │ │ │ ├── IndentAction.java │ │ │ │ │ ├── JIndentAction.java │ │ │ │ │ ├── JUnindentAction.java │ │ │ │ │ ├── JavaIndentAction.java │ │ │ │ │ ├── MapCompletionAction.java │ │ │ │ │ ├── PairAction.java │ │ │ │ │ ├── RedoAction.java │ │ │ │ │ ├── ReplaceDialog.form │ │ │ │ │ ├── ReplaceDialog.java │ │ │ │ │ ├── SmartIndent.java │ │ │ │ │ ├── SyntaxAction.java │ │ │ │ │ ├── ToggleCommentsAction.java │ │ │ │ │ ├── UndoAction.java │ │ │ │ │ └── UnindentAction.java │ │ │ │ ├── components/ │ │ │ │ │ ├── LineNumbersRuler.java │ │ │ │ │ ├── Markers.java │ │ │ │ │ ├── PairsMarker.java │ │ │ │ │ ├── SyntaxComponent.java │ │ │ │ │ └── TokenMarker.java │ │ │ │ ├── syntaxkits/ │ │ │ │ │ ├── BashSyntaxKit.java │ │ │ │ │ ├── CSyntaxKit.java │ │ │ │ │ ├── ClojureSyntaxKit.java │ │ │ │ │ ├── CppSyntaxKit.java │ │ │ │ │ ├── DOSBatchSyntaxKit.java │ │ │ │ │ ├── GroovySyntaxKit.java │ │ │ │ │ ├── JFlexSyntaxKit.java │ │ │ │ │ ├── JavaScriptSyntaxKit.java │ │ │ │ │ ├── JavaSyntaxKit.java │ │ │ │ │ ├── PropertiesSyntaxKit.java │ │ │ │ │ ├── PythonSyntaxKit.java │ │ │ │ │ ├── RubySyntaxKit.java │ │ │ │ │ ├── ScalaSyntaxKit.java │ │ │ │ │ ├── SqlSyntaxKit.java │ │ │ │ │ ├── TALSyntaxKit.java │ │ │ │ │ └── XmlSyntaxKit.java │ │ │ │ └── util/ │ │ │ │ ├── Configuration.java │ │ │ │ └── JarServiceProvider.java │ │ │ ├── jflex/ │ │ │ │ └── jsyntaxpane/ │ │ │ │ └── lexers/ │ │ │ │ ├── bash.flex │ │ │ │ ├── c.flex │ │ │ │ ├── clojure.flex │ │ │ │ ├── cpp.flex │ │ │ │ ├── dosbatch.flex │ │ │ │ ├── groovy.flex │ │ │ │ ├── java.flex │ │ │ │ ├── javascript.flex │ │ │ │ ├── jflex.flex │ │ │ │ ├── properties.flex │ │ │ │ ├── python.flex │ │ │ │ ├── ruby.flex │ │ │ │ ├── scala.flex │ │ │ │ ├── sql.flex │ │ │ │ ├── tal.flex │ │ │ │ └── xml.flex │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── services/ │ │ │ ├── jsyntaxpane.config.properties │ │ │ ├── jsyntaxpane.groovysyntaxkit.completions.properties │ │ │ ├── jsyntaxpane.javasyntaxkit.completions.properties │ │ │ ├── jsyntaxpane.kitsfortypes.properties │ │ │ └── jsyntaxpane.syntaxstyles.properties │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ ├── release/ │ │ │ └── modules/ │ │ │ └── ext/ │ │ │ └── jsyntaxpane-0.9.4-visualvm.jar │ │ └── src/ │ │ └── jsyntaxpane/ │ │ └── lib/ │ │ ├── Bundle.properties │ │ └── Installer.java │ ├── mbeans/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── mbeans/ │ │ ├── BorderedComponent.java │ │ ├── Bundle.properties │ │ ├── Formatter.java │ │ ├── IconManager.java │ │ ├── Install.java │ │ ├── MBeansAttributesView.java │ │ ├── MBeansMetadataView.java │ │ ├── MBeansNotificationsView.java │ │ ├── MBeansOperationsView.java │ │ ├── MBeansTab.java │ │ ├── MBeansTreeView.java │ │ ├── MBeansView.java │ │ ├── MBeansViewProvider.java │ │ ├── MBeansViewsSupport.java │ │ ├── OperationEntry.java │ │ ├── Plotter.java │ │ ├── PlotterPanel.java │ │ ├── Resources.java │ │ ├── TableSorter.java │ │ ├── ThreadDialog.java │ │ ├── Utilities.java │ │ ├── Utils.java │ │ ├── VariableGridLayout.java │ │ ├── XArrayDataViewer.java │ │ ├── XDataViewer.java │ │ ├── XMBean.java │ │ ├── XMBeanAttributes.java │ │ ├── XMBeanInfo.java │ │ ├── XMBeanNotifications.java │ │ ├── XMBeanOperations.java │ │ ├── XNodeInfo.java │ │ ├── XObject.java │ │ ├── XOpenTypeViewer.java │ │ ├── XPlotter.java │ │ ├── XPlottingViewer.java │ │ ├── XSheet.java │ │ ├── XTable.java │ │ ├── XTextField.java │ │ ├── XTextFieldEditor.java │ │ ├── XTree.java │ │ ├── XTreeRenderer.java │ │ └── options/ │ │ ├── Bundle.properties │ │ ├── GlobalPreferences.java │ │ ├── MBeansOptionsPanel.java │ │ └── MBeansOptionsPanelController.java │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── platform.properties │ │ ├── platform.xml │ │ ├── project.properties │ │ └── project.xml │ ├── oqlsyntax/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ ├── resources/ │ │ │ ├── README.txt │ │ │ └── oql.flex │ │ └── src/ │ │ ├── META-INF/ │ │ │ └── services/ │ │ │ ├── jsyntaxpane.config.properties │ │ │ ├── jsyntaxpane.kitsfortypes.properties │ │ │ └── jsyntaxpane.oqlsyntaxkit.completions.properties │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── oqlsyntax/ │ │ ├── Bundle.properties │ │ ├── OQLSyntaxEditor.java │ │ ├── OqlLexer.java │ │ └── OqlSyntaxKit.java │ ├── saplugin/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── saplugin/ │ │ ├── Agent.java │ │ ├── Arguments.java │ │ ├── Bundle.properties │ │ ├── CodeViewerPanel.java │ │ ├── FindInCodeCachePanel.java │ │ ├── FindInHeapPanel.java │ │ ├── FindPointerPanel.java │ │ ├── Inspector.java │ │ ├── Installer.java │ │ ├── JavaStackTracePanel.java │ │ ├── JavaThreadsPanel.java │ │ ├── OopInspectorView.java │ │ ├── OopTreeNodeAdapter.java │ │ ├── ProxyListener.java │ │ ├── SAModelImpl.java │ │ ├── SAModelProvider.java │ │ ├── SAObject.java │ │ ├── SAPluginClassLoader.java │ │ ├── SAView.java │ │ ├── SAViewProvider.java │ │ ├── SAWrapper.java │ │ ├── StackTrace.java │ │ └── VM.java │ ├── security/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── security/ │ │ ├── Bundle.properties │ │ ├── Installer.java │ │ ├── PersistenceSupport.java │ │ ├── SecurityModel.java │ │ ├── SecurityOptionsPanel.java │ │ ├── SecurityOptionsPanelController.java │ │ └── ValuesCustomizer.java │ ├── startupprofiler/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── profiler/ │ │ └── startup/ │ │ ├── Bundle.properties │ │ ├── Dialogs.java │ │ ├── StartupConfigurator.java │ │ ├── StartupProfiler.java │ │ ├── StartupProfilerAction.java │ │ └── resources/ │ │ └── layer.xml │ ├── systray/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── systray/ │ │ ├── Bundle.properties │ │ ├── Install.java │ │ ├── SysTray.java │ │ └── SysTrayPreferences.java │ ├── threadinspect/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── threadinspect/ │ │ ├── Bundle.properties │ │ ├── Engine.java │ │ ├── Installer.java │ │ ├── JExtendedSplitPane.java │ │ └── ThreadsInspector.java │ ├── tracer/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── tracer/ │ │ ├── ItemValueFormatter.java │ │ ├── PackageStateHandler.java │ │ ├── ProbeItemDescriptor.java │ │ ├── ProbeStateHandler.java │ │ ├── SessionInitializationException.java │ │ ├── TracerPackage.java │ │ ├── TracerPackageProvider.java │ │ ├── TracerProbe.java │ │ ├── TracerProbeDescriptor.java │ │ ├── TracerProgressObject.java │ │ ├── TracerSupport.java │ │ ├── impl/ │ │ │ ├── Bundle.properties │ │ │ ├── DetailsView.java │ │ │ ├── PackagesView.java │ │ │ ├── TimelineView.java │ │ │ ├── TracerController.java │ │ │ ├── TracerModel.java │ │ │ ├── TracerSupportImpl.java │ │ │ ├── TracerView.java │ │ │ ├── TracerViewProvider.java │ │ │ ├── details/ │ │ │ │ ├── DetailsPanel.java │ │ │ │ ├── DetailsTable.java │ │ │ │ ├── DetailsTableCellRenderer.java │ │ │ │ ├── DetailsTableModel.java │ │ │ │ ├── ItemValueRenderer.java │ │ │ │ ├── MarkRenderer.java │ │ │ │ └── TimestampRenderer.java │ │ │ ├── export/ │ │ │ │ ├── CSVExporter.java │ │ │ │ ├── DataExport.java │ │ │ │ ├── ExportBatch.java │ │ │ │ ├── Exporter.java │ │ │ │ ├── HTMLExporter.java │ │ │ │ └── XMLExporter.java │ │ │ ├── options/ │ │ │ │ ├── TracerOptions.java │ │ │ │ ├── TracerOptionsPanel.java │ │ │ │ └── TracerOptionsPanelController.java │ │ │ ├── probes/ │ │ │ │ ├── ProbeDescriptorComponent.java │ │ │ │ └── ProbePresenter.java │ │ │ ├── swing/ │ │ │ │ ├── CategoryList.java │ │ │ │ ├── ColorIcon.java │ │ │ │ ├── CustomComboRenderer.java │ │ │ │ ├── DropdownButton.java │ │ │ │ ├── EnhancedLabelRenderer.java │ │ │ │ ├── HeaderButton.java │ │ │ │ ├── HeaderLabel.java │ │ │ │ ├── HeaderPanel.java │ │ │ │ ├── LabelRenderer.java │ │ │ │ ├── LegendFont.java │ │ │ │ ├── ScrollBar.java │ │ │ │ ├── SimpleSeparator.java │ │ │ │ ├── TimelineMarksPainter.java │ │ │ │ └── VisibilityHandler.java │ │ │ └── timeline/ │ │ │ ├── ChartPanel.java │ │ │ ├── ContinuousXYPainter.java │ │ │ ├── DiscreteXYPainter.java │ │ │ ├── PointsComputer.java │ │ │ ├── ProbesPanel.java │ │ │ ├── RowBackgroundDecorator.java │ │ │ ├── RowBoundsDecorator.java │ │ │ ├── RowForegroundDecorator.java │ │ │ ├── TimelineAxis.java │ │ │ ├── TimelineChart.java │ │ │ ├── TimelineColorFactory.java │ │ │ ├── TimelineLegendOverlay.java │ │ │ ├── TimelineModel.java │ │ │ ├── TimelinePaintersFactory.java │ │ │ ├── TimelinePanel.java │ │ │ ├── TimelineSelectionOverlay.java │ │ │ ├── TimelineSupport.java │ │ │ ├── TimelineTooltipOverlay.java │ │ │ ├── TimelineTooltipPainter.java │ │ │ ├── TimelineUnitsOverlay.java │ │ │ ├── TimelineXYItem.java │ │ │ ├── TimelineXYPainter.java │ │ │ ├── VerticalTimelineLayout.java │ │ │ └── items/ │ │ │ ├── ContinuousXYItemDescriptor.java │ │ │ ├── DiscreteXYItemDescriptor.java │ │ │ ├── ValueItemDescriptor.java │ │ │ └── XYItemDescriptor.java │ │ └── package-info.java │ ├── tracercollect/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── tracer/ │ │ └── collections/ │ │ ├── Bundle.properties │ │ └── resources/ │ │ ├── CollectionsTracer.btrace │ │ ├── collections_traces.js │ │ └── layer.xml │ ├── tracerdtrace/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ ├── release/ │ │ │ └── modules/ │ │ │ └── ext/ │ │ │ └── dtrace.jar │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── tracer/ │ │ └── dtrace/ │ │ ├── Bundle.properties │ │ ├── BytesIOProbe.java │ │ ├── CpusMonitorProbe.java │ │ ├── DTracePackage.java │ │ ├── DTracePackageProvider.java │ │ ├── Installer.java │ │ ├── JVMOverheadProbe.java │ │ ├── SyscallsProbe.java │ │ └── resources/ │ │ └── probes.d │ ├── tracerdynamic/ │ │ ├── build.xml │ │ ├── doc/ │ │ │ ├── QuickStart.txt │ │ │ └── Sample.js │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── tracer/ │ │ └── dynamic/ │ │ ├── Bundle.properties │ │ ├── impl/ │ │ │ ├── DynamicPackage.java │ │ │ ├── DynamicPackageProvider.java │ │ │ ├── DynamicProbe.java │ │ │ ├── ItemValueFormatterInterface.java │ │ │ ├── ItemValueFormatterProxy.java │ │ │ └── ValueProvider.java │ │ ├── jmx/ │ │ │ ├── JMXValueCache.java │ │ │ └── JMXValueProvider.java │ │ ├── resources/ │ │ │ └── configurator.js │ │ └── spi/ │ │ └── DeployerImpl.java │ ├── tracerio/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── tracer/ │ │ └── io/ │ │ ├── Bundle.properties │ │ ├── layer.xml │ │ └── resources/ │ │ ├── IOTracer.btrace │ │ └── io_traces.js │ ├── tracerjavafx/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── tracer/ │ │ └── javafx/ │ │ ├── Bundle.properties │ │ ├── fx_tracer.js │ │ ├── layer.xml │ │ └── resources/ │ │ └── JavaFXTracer.probe │ ├── tracerjvm/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── tracer/ │ │ └── jvm/ │ │ ├── Bundle.properties │ │ ├── layer.xml │ │ └── resources/ │ │ ├── JavaIOTracer.btrace │ │ └── platform_mx.js │ ├── tracerjvmstat/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── tracer/ │ │ └── jvmstat/ │ │ ├── Bundle.properties │ │ ├── Install.java │ │ ├── JvmstatCounterFormatter.java │ │ ├── JvmstatCounterProbe.java │ │ ├── JvmstatCountersPackage.java │ │ ├── JvmstatCountersPackageProvider.java │ │ ├── JvmstatCountersPackages.java │ │ └── Utils.java │ ├── tracermonitor/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── tracer/ │ │ └── monitor/ │ │ ├── Bundle.properties │ │ ├── ClassesMonitorProbe.java │ │ ├── CpuMonitorProbe.java │ │ ├── HeapMonitorProbe.java │ │ ├── MonitorPackage.java │ │ ├── MonitorPackageProvider.java │ │ ├── MonitorProbe.java │ │ ├── PermgenMonitorProbe.java │ │ └── ThreadsMonitorProbe.java │ └── tracerswing/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── modules/ │ └── tracer/ │ └── swing/ │ ├── Bundle.properties │ ├── layer.xml │ └── resources/ │ ├── AWTTracer.btrace │ ├── SwingTracer.btrace │ └── swing_traces.js ├── samples/ │ ├── apptype/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── platform.properties │ │ │ ├── project.properties │ │ │ └── project.xml │ │ └── src/ │ │ └── org/ │ │ └── visualvm/ │ │ └── demoapplicationtype/ │ │ ├── AnagramAction.java │ │ ├── AnagramApplicationType.java │ │ ├── AnagramApplicationTypeFactory.java │ │ ├── AnagramOverview.java │ │ ├── AnagramViewPluginProvider.java │ │ ├── Bundle.properties │ │ ├── Installer.java │ │ └── layer.xml │ ├── datasource/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── platform.properties │ │ │ ├── project.properties │ │ │ └── project.xml │ │ └── src/ │ │ └── org/ │ │ └── visualvm/ │ │ └── demodescriptorprovider/ │ │ ├── Bundle.properties │ │ ├── DemoDataSource.java │ │ ├── DemoDataSourceDescriptor.java │ │ ├── DemoDataSourceDescriptorProvider.java │ │ ├── DemoDataSourceView.java │ │ ├── DemoDataSourceViewProvider.java │ │ ├── Installer.java │ │ └── panels/ │ │ ├── MemoryMonitor1.java │ │ ├── MemoryMonitor2.java │ │ ├── MemoryMonitor3.java │ │ ├── MemoryMonitor4.java │ │ └── MemoryMonitor5.java │ ├── filtersortsample/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── platform.properties │ │ │ ├── project.properties │ │ │ └── project.xml │ │ └── src/ │ │ └── org/ │ │ └── visualvm/ │ │ └── samples/ │ │ └── filtersortsample/ │ │ ├── Bundle.properties │ │ ├── Controller.java │ │ ├── FilterSortNode.java │ │ ├── FilterSortRootNode.java │ │ ├── Install.java │ │ └── layer.xml │ ├── hellovvm/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── platform.properties │ │ │ ├── project.properties │ │ │ └── project.xml │ │ └── src/ │ │ └── org/ │ │ └── hellovisualvm/ │ │ ├── Bundle.properties │ │ ├── HelloWorldView.java │ │ ├── HelloWorldViewProvider.java │ │ └── Installer.java │ ├── hostcompare/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── platform.properties │ │ │ ├── project.properties │ │ │ └── project.xml │ │ └── src/ │ │ └── org/ │ │ └── nb/ │ │ └── hostcompare/ │ │ ├── Bundle.properties │ │ ├── HostView.java │ │ ├── HostViewProvider.java │ │ ├── HostViewSupport.java │ │ ├── Installer.java │ │ └── SystemPropertiesViewSupport.java │ ├── jvmcap/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── platform.properties │ │ │ ├── project.properties │ │ │ └── project.xml │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── modules/ │ │ └── jvmcap/ │ │ ├── ApplicationSnapshotViewPluginProvider.java │ │ ├── ApplicationViewPluginProvider.java │ │ ├── Bundle.properties │ │ ├── Installer.java │ │ ├── JvmCapabilitiesModel.java │ │ ├── JvmCapabilitiesViewComponent.java │ │ └── JvmCapabilitiesViewPlugin.java │ ├── pluggableViewDemoSuite/ │ │ ├── build.xml │ │ ├── helloWorldPluggableView/ │ │ │ ├── build.xml │ │ │ ├── manifest.mf │ │ │ ├── nbproject/ │ │ │ │ ├── build-impl.xml │ │ │ │ ├── genfiles.properties │ │ │ │ ├── platform.properties │ │ │ │ ├── project.properties │ │ │ │ ├── project.xml │ │ │ │ └── suite.properties │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── hellovisualvm/ │ │ │ ├── Bundle.properties │ │ │ ├── HelloWorldView.java │ │ │ ├── HelloWorldViewProvider.java │ │ │ └── HelloWorldViewSupport.java │ │ ├── helloWorldViewPlugin/ │ │ │ ├── build.xml │ │ │ ├── manifest.mf │ │ │ ├── nbproject/ │ │ │ │ ├── build-impl.xml │ │ │ │ ├── genfiles.properties │ │ │ │ ├── platform.properties │ │ │ │ ├── project.properties │ │ │ │ ├── project.xml │ │ │ │ └── suite.properties │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── netbeans/ │ │ │ └── helloworldplugin/ │ │ │ ├── Bundle.properties │ │ │ ├── HelloWorldViewPlugin.java │ │ │ ├── HelloWorldViewPluginProvider.java │ │ │ ├── Installer.java │ │ │ └── layer.xml │ │ └── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── platform.properties │ │ ├── project.properties │ │ └── project.xml │ ├── sampleBundle/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── platform.properties │ │ │ ├── project.properties │ │ │ └── project.xml │ │ └── src/ │ │ └── org/ │ │ └── nb/ │ │ └── samplebundle/ │ │ ├── Bundle.properties │ │ ├── apptype/ │ │ │ ├── Bundle.properties │ │ │ ├── apptypeDescription.html │ │ │ ├── apptypePanelVisual.form │ │ │ ├── apptypePanelVisual.java │ │ │ ├── apptypeWizardIterator.java │ │ │ └── apptypeWizardPanel.java │ │ ├── datasource/ │ │ │ ├── Bundle.properties │ │ │ ├── datasourceDescription.html │ │ │ ├── datasourcePanelVisual.form │ │ │ ├── datasourcePanelVisual.java │ │ │ ├── datasourceWizardIterator.java │ │ │ └── datasourceWizardPanel.java │ │ ├── hellovvm/ │ │ │ ├── Bundle.properties │ │ │ ├── hellovvmDescription.html │ │ │ ├── hellovvmPanelVisual.form │ │ │ ├── hellovvmPanelVisual.java │ │ │ ├── hellovvmWizardIterator.java │ │ │ └── hellovvmWizardPanel.java │ │ ├── hostview/ │ │ │ ├── Bundle.properties │ │ │ ├── hostviewDescription.html │ │ │ ├── hostviewPanelVisual.form │ │ │ ├── hostviewPanelVisual.java │ │ │ ├── hostviewWizardIterator.java │ │ │ └── hostviewWizardPanel.java │ │ ├── jvmcaps/ │ │ │ ├── Bundle.properties │ │ │ ├── jvmcapsDescription.html │ │ │ ├── jvmcapsPanelVisual.form │ │ │ ├── jvmcapsPanelVisual.java │ │ │ ├── jvmcapsWizardIterator.java │ │ │ └── jvmcapsWizardPanel.java │ │ ├── layer.xml │ │ ├── pluggableViewDemoSuite/ │ │ │ ├── Bundle.properties │ │ │ ├── pluggableViewDemoSuiteDescription.html │ │ │ ├── pluggableViewDemoSuitePanelVisual.form │ │ │ ├── pluggableViewDemoSuitePanelVisual.java │ │ │ ├── pluggableViewDemoSuiteWizardIterator.java │ │ │ └── pluggableViewDemoSuiteWizardPanel.java │ │ └── subnodes/ │ │ ├── Bundle.properties │ │ ├── subnodesDescription.html │ │ ├── subnodesPanelVisual.form │ │ ├── subnodesPanelVisual.java │ │ ├── subnodesWizardIterator.java │ │ └── subnodesWizardPanel.java │ └── subnodes/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── platform.properties │ │ ├── project.properties │ │ └── project.xml │ └── src/ │ └── org/ │ └── visualvm/ │ └── demoapplicationtype/ │ ├── Bundle.properties │ ├── Installer.java │ ├── application/ │ │ ├── AnagramApplication.java │ │ ├── AnagramApplicationProvider.java │ │ └── AnagramMbeansModule.java │ ├── applicationtype/ │ │ ├── AnagramApplicationType.java │ │ └── AnagramApplicationTypeFactory.java │ ├── datasource/ │ │ ├── AnagramDataSource.java │ │ └── AnagramDataSourceDescriptorProvider.java │ └── model/ │ ├── AnagramModel.java │ └── AnagramModelProvider.java ├── templates/ │ └── apisupport/ │ ├── build.xml │ ├── javahelp/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── apisupport/ │ │ └── docs/ │ │ ├── visualvmview-about.html │ │ ├── visualvmview-hs.xml │ │ ├── visualvmview-idx.xml │ │ ├── visualvmview-map.xml │ │ └── visualvmview-toc.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── platform.properties │ │ ├── project.properties │ │ └── project.xml │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── apisupport/ │ ├── Bundle.properties │ ├── actions/ │ │ ├── Bundle.properties │ │ ├── NameAndLocationPanel.form │ │ ├── NameAndLocationPanel.java │ │ ├── NewActionIterator.java │ │ ├── templateAction.javx │ │ └── visualVMAction.html │ ├── apptypes/ │ │ ├── Bundle.properties │ │ ├── NameAndLocationPanel.form │ │ ├── NameAndLocationPanel.java │ │ ├── NewProjectIterator.java │ │ ├── templateApplicationType.javx │ │ ├── templateApplicationTypeProvider.javx │ │ ├── templateMainClassApplicationTypeProvider.javx │ │ └── visualVMAppType.html │ ├── datasources/ │ │ ├── Bundle.properties │ │ ├── NameAndLocationPanel.form │ │ ├── NameAndLocationPanel.java │ │ ├── NewProjectIterator.java │ │ ├── templateVisualVMDataSource.javx │ │ ├── templateVisualVMDataSourceProvider.javx │ │ └── visualVMDatasource.html │ ├── layer.xml │ ├── models/ │ │ ├── Bundle.properties │ │ ├── NameAndLocationPanel.form │ │ ├── NameAndLocationPanel.java │ │ ├── NewProjectIterator.java │ │ ├── templateVisualVMModel.javx │ │ ├── templateVisualVMModelFactory.javx │ │ ├── templateVisualVMModelProvider.javx │ │ └── visualVMModel.html │ ├── subtabs/ │ │ ├── Bundle.properties │ │ ├── NameAndLocationPanel.form │ │ ├── NameAndLocationPanel.java │ │ ├── NewProjectIterator.java │ │ ├── templateVisualVMViewPlugin.javx │ │ ├── templateVisualVMViewPluginProvider.javx │ │ └── visualVMSubTab.html │ └── tabs/ │ ├── Bundle.properties │ ├── NameAndLocationPanel.form │ ├── NameAndLocationPanel.java │ ├── NewProjectIterator.java │ ├── templateVisualVMView.javx │ ├── templateVisualVMViewProvider.javx │ ├── visualVMView.html │ └── visualvmview-helpset.xml └── visualvm/ ├── antsrc/ │ └── org/ │ └── netbeans/ │ └── nbbuild/ │ ├── AutoUpdate.java │ └── AutoUpdateCatalogParser.java ├── application/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── application/ │ ├── Application.java │ ├── ApplicationDescriptor.java │ ├── ApplicationDescriptorProvider.java │ ├── ApplicationFinder.java │ ├── ApplicationSupport.java │ ├── ApplicationsSorting.java │ ├── Bundle.properties │ ├── GeneralPropertiesProvider.java │ ├── Installer.java │ ├── RemoveFinishedApplicationsAction.java │ ├── jvm/ │ │ ├── DefaultJvm.java │ │ ├── HeapHistogram.java │ │ ├── Jvm.java │ │ ├── JvmFactory.java │ │ ├── MonitoredData.java │ │ ├── MonitoredDataListener.java │ │ └── package-info.java │ ├── options/ │ │ ├── Bundle.properties │ │ └── Open.java │ ├── package-info.java │ ├── resources/ │ │ ├── Bundle.properties │ │ └── layer.xml │ ├── snapshot/ │ │ ├── AddApplicationSnapshotAction.java │ │ ├── ApplicationSnapshot.java │ │ ├── ApplicationSnapshotAction.java │ │ ├── ApplicationSnapshotCategory.java │ │ ├── ApplicationSnapshotConfigurator.java │ │ ├── ApplicationSnapshotDescriptor.java │ │ ├── ApplicationSnapshotDescriptorProvider.java │ │ ├── ApplicationSnapshotProvider.java │ │ ├── ApplicationSnapshotsSupport.java │ │ ├── Bundle.properties │ │ └── package-info.java │ └── type/ │ ├── ApplicationType.java │ ├── ApplicationTypeFactory.java │ ├── Bundle.properties │ ├── DefaultApplicationType.java │ ├── EclipseApplicationType.java │ ├── EclipseApplicationTypeFactory.java │ ├── IntellijApplicationType.java │ ├── IntellijApplicationTypeFactory.java │ ├── JDeveloperApplicationType.java │ ├── JDeveloperApplicationTypeFactory.java │ ├── JavaPluginApplicationType.java │ ├── JavaPluginApplicationTypeFactory.java │ ├── JavaWebStartApplicationType.java │ ├── JavaWebStartApplicationTypeFactory.java │ ├── MainClassApplicationType.java │ ├── MainClassApplicationTypeFactory.java │ ├── MavenApplicationType.java │ ├── MavenApplicationTypeFactory.java │ ├── NetBeans3xApplicationType.java │ ├── NetBeansApplicationType.java │ ├── NetBeansApplicationTypeFactory.java │ ├── NetBeansBasedApplicationType.java │ ├── VisualVMApplicationType.java │ └── package-info.java ├── applicationviews/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── application/ │ └── views/ │ ├── ApplicationThreadsResponseProvider.java │ ├── ApplicationViewsSupport.java │ ├── Installer.java │ ├── monitor/ │ │ ├── ApplicationMonitorModel.java │ │ ├── ApplicationMonitorView.java │ │ ├── ApplicationMonitorViewProvider.java │ │ ├── ApplicationSnapshotMonitorViewProvider.java │ │ └── Bundle.properties │ ├── overview/ │ │ ├── ApplicationOverviewModel.java │ │ ├── ApplicationOverviewView.java │ │ ├── ApplicationOverviewViewProvider.java │ │ ├── ApplicationSnapshotOverviewViewProvider.java │ │ ├── Bundle.properties │ │ └── OverviewViewSupport.java │ ├── package-info.java │ ├── resources/ │ │ └── Bundle.properties │ └── threads/ │ ├── ApplicationSnapshotThreadsViewProvider.java │ ├── ApplicationThreadsView.java │ ├── ApplicationThreadsViewProvider.java │ ├── Bundle.properties │ ├── DeadlockDetector.java │ ├── PersistenceSupport.java │ ├── ThreadMXBeanDataManager.java │ └── VisualVMThreadsDataManager.java ├── appui/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── modules/ │ └── appui/ │ ├── AboutAction.java │ ├── Bundle.properties │ ├── Install.java │ ├── Standard.xml │ ├── WindowManager.wswmgr │ ├── about/ │ │ ├── AboutDialog.java │ │ ├── AboutDialogControls.java │ │ ├── AboutDialogPanel.java │ │ ├── Bundle.properties │ │ ├── TextBrowser.java │ │ └── TextViewerComponent.java │ ├── actions/ │ │ └── VisualVMActionsSupportProvider.java │ ├── keystore/ │ │ ├── CacertsKeyStoreProvider.java │ │ ├── VisualVMKeyStoreProvider.java │ │ └── ide.ks │ ├── layer.xml │ ├── options/ │ │ ├── Bundle.properties │ │ ├── FiltersOptionsCategory.java │ │ ├── FiltersOptionsPanel.java │ │ ├── NetworkOptionsModel.java │ │ ├── NetworkOptionsPanel.java │ │ ├── NetworkOptionsPanelController.java │ │ └── ProxySettings.java │ ├── proxysettings/ │ │ └── ProxySettingsHack.java │ ├── toolbar/ │ │ ├── ToolbarProvider.java │ │ └── VisualVMToolbar.java │ ├── url/ │ │ └── VisualVMURLDisplayer.java │ └── welcome/ │ ├── Bundle.properties │ ├── BundleSupport.java │ ├── CaptionPanel.java │ ├── Constants.java │ ├── ContentsPanel.java │ ├── FixedImagePanel.java │ ├── FooterPanel.java │ ├── HorizontalImagePanel.java │ ├── LinkButton.java │ ├── Logo.java │ ├── ShowNextTime.java │ ├── ShowWelcomeAction.java │ ├── StartPageContent.java │ ├── Utils.java │ ├── WebLink.java │ ├── WelcomeComponent.java │ ├── WelcomeOptions.java │ └── resources/ │ ├── Bundle.properties │ ├── VisualVMWelcome.settings │ └── VisualVMWelcome.wstcref ├── attach/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── attach/ │ ├── AttachModelImpl.java │ ├── AttachModelProvider.java │ ├── Bundle.properties │ ├── HeapHistogramImpl.java │ ├── Installer.java │ ├── JRockitAttachModelImpl.java │ ├── JRockitHeapHistogramImpl.java │ └── OracleJRockitAttachModelImpl.java ├── branding/ │ ├── core/ │ │ └── core.jar/ │ │ └── org/ │ │ └── netbeans/ │ │ └── core/ │ │ └── startup/ │ │ └── Bundle.properties │ └── modules/ │ ├── ext/ │ │ └── updater.jar/ │ │ └── org/ │ │ └── netbeans/ │ │ └── updater/ │ │ └── Bundle.properties │ ├── org-netbeans-core-windows.jar/ │ │ └── org/ │ │ └── netbeans/ │ │ └── core/ │ │ └── windows/ │ │ ├── Bundle.properties │ │ ├── options/ │ │ │ └── Bundle.properties │ │ └── view/ │ │ └── ui/ │ │ └── Bundle.properties │ ├── org-netbeans-core.jar/ │ │ └── org/ │ │ └── netbeans/ │ │ └── core/ │ │ └── ui/ │ │ └── Bundle.properties │ ├── org-netbeans-modules-autoupdate-ui.jar/ │ │ └── org/ │ │ └── netbeans/ │ │ └── modules/ │ │ └── autoupdate/ │ │ └── ui/ │ │ └── Bundle.properties │ ├── org-netbeans-modules-profiler.jar/ │ │ └── org/ │ │ └── netbeans/ │ │ └── modules/ │ │ └── profiler/ │ │ ├── Bundle.properties │ │ └── heapwalk/ │ │ └── model/ │ │ └── Bundle.properties │ └── org-netbeans-swing-laf-flatlaf.jar/ │ └── org/ │ └── netbeans/ │ └── swing/ │ └── laf/ │ └── flatlaf/ │ └── Bundle.properties ├── build-nb.sh ├── build.xml ├── caching.api/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ ├── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── api/ │ │ └── caching/ │ │ ├── Bundle.properties │ │ ├── Cache.java │ │ ├── CacheFactory.java │ │ ├── Entry.java │ │ ├── EntryFactory.java │ │ ├── Persistor.java │ │ ├── impl/ │ │ │ ├── CacheFactoryImpl.java │ │ │ ├── CacheImpl.java │ │ │ ├── KeyFactory.java │ │ │ ├── SoftKeyFactory.java │ │ │ ├── SoftReferenceEx.java │ │ │ ├── WeakKeyFactory.java │ │ │ ├── WeakReferenceEx.java │ │ │ └── package-info.java │ │ └── package-info.java │ └── test/ │ └── unit/ │ └── src/ │ └── com/ │ └── sun/ │ └── tools/ │ └── visualvm/ │ └── api/ │ └── caching/ │ ├── CacheImplTest.java │ └── impl/ │ ├── SoftReferenceExTest.java │ └── WeakReferenceExTest.java ├── charts/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ ├── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── charts/ │ │ ├── Bundle.properties │ │ ├── ChartFactory.java │ │ ├── ColorFactory.java │ │ ├── SimpleXYChartDescriptor.java │ │ ├── SimpleXYChartSupport.java │ │ ├── package-info.java │ │ ├── swing/ │ │ │ └── RotateLabelUI.java │ │ └── xy/ │ │ ├── Bundle.properties │ │ ├── ColorIcon.java │ │ ├── SimpleXYChart.java │ │ ├── SimpleXYChartUtils.java │ │ ├── XYAxisComponent.java │ │ ├── XYBackground.java │ │ ├── XYDecimalMarksPainter.java │ │ ├── XYItem.java │ │ ├── XYPainter.java │ │ ├── XYPaintersModel.java │ │ ├── XYPercentMarksPainter.java │ │ ├── XYSelectionOverlay.java │ │ ├── XYStorage.java │ │ ├── XYTooltipModel.java │ │ ├── XYTooltipOverlay.java │ │ └── XYTooltipPainter.java │ └── test/ │ └── unit/ │ └── src/ │ └── test/ │ └── Demo.java ├── core/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ ├── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── core/ │ │ ├── Bundle.properties │ │ ├── Install.java │ │ ├── VisualVM.java │ │ ├── datasource/ │ │ │ ├── DataSource.java │ │ │ ├── DataSourceContainer.java │ │ │ ├── DataSourceProvider.java │ │ │ ├── DataSourceRepository.java │ │ │ ├── StatefulDataSource.java │ │ │ ├── Storage.java │ │ │ ├── descriptor/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── DataSourceDescriptor.java │ │ │ │ ├── DataSourceDescriptorFactory.java │ │ │ │ ├── GeneralPropertiesProvider.java │ │ │ │ └── package-info.java │ │ │ └── package-info.java │ │ ├── datasupport/ │ │ │ ├── AsyncPropertyChangeSupport.java │ │ │ ├── ClassNameComparator.java │ │ │ ├── ComparableWeakReference.java │ │ │ ├── DataChangeEvent.java │ │ │ ├── DataChangeListener.java │ │ │ ├── DataChangeSupport.java │ │ │ ├── DataRemovedListener.java │ │ │ ├── Positionable.java │ │ │ ├── Stateful.java │ │ │ ├── Utils.java │ │ │ └── package-info.java │ │ ├── explorer/ │ │ │ ├── Bundle.properties │ │ │ ├── DataSourcesComparator.java │ │ │ ├── ExplorerComponent.java │ │ │ ├── ExplorerContextMenuFactory.java │ │ │ ├── ExplorerExpansionListener.java │ │ │ ├── ExplorerModelBuilder.java │ │ │ ├── ExplorerNode.java │ │ │ ├── ExplorerNodeRenderer.java │ │ │ ├── ExplorerNodesComparator.java │ │ │ ├── ExplorerSelectionListener.java │ │ │ ├── ExplorerSupport.java │ │ │ ├── ExplorerTopComponent.java │ │ │ ├── ExplorerTopComponentAction.java │ │ │ └── package-info.java │ │ ├── layer.xml │ │ ├── model/ │ │ │ ├── AbstractModelProvider.java │ │ │ ├── Model.java │ │ │ ├── ModelCache.java │ │ │ ├── ModelFactory.java │ │ │ ├── ModelProvider.java │ │ │ └── package-info.java │ │ ├── options/ │ │ │ ├── Bundle.properties │ │ │ ├── GeneralOptionsPanel.java │ │ │ ├── GeneralOptionsPanelController.java │ │ │ ├── GlobalPreferences.java │ │ │ ├── UISupport.java │ │ │ └── package-info.java │ │ ├── properties/ │ │ │ ├── Bundle.properties │ │ │ ├── EditPropertiesAction.java │ │ │ ├── PropertiesConfigurator.java │ │ │ ├── PropertiesCustomizer.java │ │ │ ├── PropertiesPanel.java │ │ │ ├── PropertiesProvider.java │ │ │ ├── PropertiesSupport.java │ │ │ └── package-info.java │ │ ├── scheduler/ │ │ │ ├── DefaultScheduledTask.java │ │ │ ├── Quantum.java │ │ │ ├── ScheduledTask.java │ │ │ ├── Scheduler.java │ │ │ ├── SchedulerTask.java │ │ │ ├── SchedulingPipe.java │ │ │ └── package-info.java │ │ ├── snapshot/ │ │ │ ├── Bundle.properties │ │ │ ├── GeneralPropertiesProvider.java │ │ │ ├── RegisteredSnapshotCategories.java │ │ │ ├── Snapshot.java │ │ │ ├── SnapshotCategoriesListener.java │ │ │ ├── SnapshotCategory.java │ │ │ ├── SnapshotDescriptor.java │ │ │ ├── SnapshotView.java │ │ │ ├── SnapshotsContainer.java │ │ │ ├── SnapshotsContainerDescriptor.java │ │ │ ├── SnapshotsSorting.java │ │ │ ├── SnapshotsSupport.java │ │ │ ├── options/ │ │ │ │ ├── Bundle.properties │ │ │ │ └── Openfile.java │ │ │ └── package-info.java │ │ └── ui/ │ │ ├── Bundle.properties │ │ ├── DataSourceCaption.java │ │ ├── DataSourceView.java │ │ ├── DataSourceViewPlugin.java │ │ ├── DataSourceViewPluginProvider.java │ │ ├── DataSourceViewProvider.java │ │ ├── DataSourceViewsManager.java │ │ ├── DataSourceWindow.java │ │ ├── DataSourceWindowListener.java │ │ ├── DataSourceWindowManager.java │ │ ├── DataSourceWindowTabbedPane.java │ │ ├── DesktopUtils.java │ │ ├── PluggableDataSourceViewProvider.java │ │ ├── actions/ │ │ │ ├── ActionUtils.java │ │ │ ├── Bundle.properties │ │ │ ├── DataSourceAction.java │ │ │ ├── DeleteSnapshotAction.java │ │ │ ├── LoadRecentSnapshot.java │ │ │ ├── LoadSnapshotAction.java │ │ │ ├── MultiDataSourceAction.java │ │ │ ├── OpenDataSourceAction.java │ │ │ ├── RemoveDataSourceAction.java │ │ │ ├── RenameConfigurator.java │ │ │ ├── RenameDataSourceAction.java │ │ │ ├── SaveSnapshotAsAction.java │ │ │ ├── SingleDataSourceAction.java │ │ │ ├── VisualVMDropHandler.java │ │ │ └── package-info.java │ │ ├── components/ │ │ │ ├── Bundle.properties │ │ │ ├── DataViewComponent.java │ │ │ ├── DisplayArea.java │ │ │ ├── DisplayAreaSupport.java │ │ │ ├── JExtendedSplitPane.java │ │ │ ├── LevelIndicator.java │ │ │ ├── NotSupportedDisplayer.java │ │ │ ├── ScrollableContainer.java │ │ │ ├── SectionSeparator.java │ │ │ ├── Spacer.java │ │ │ └── package-info.java │ │ ├── options/ │ │ │ ├── Bundle.properties │ │ │ └── WindowToFront.java │ │ ├── package-info.java │ │ └── resources/ │ │ ├── ExplorerTopComponentSettings.xml │ │ └── ExplorerTopComponentWstcref.xml │ └── test/ │ └── unit/ │ └── src/ │ └── com/ │ └── sun/ │ └── tools/ │ └── visualvm/ │ └── core/ │ └── scheduler/ │ ├── DefaultScheduledTaskTest.java │ ├── QuantumTest.java │ └── SchedulerTest.java ├── coredump/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── coredump/ │ ├── Bundle.properties │ ├── CoreDump.java │ ├── CoreDumpDescriptor.java │ ├── CoreDumpSupport.java │ ├── CoreDumpsContainer.java │ ├── CoreDumpsContainerDescriptor.java │ ├── CoreDumpsSorting.java │ ├── Installer.java │ ├── impl/ │ │ ├── AddVMCoredumpAction.java │ │ ├── Bundle.properties │ │ ├── CoreDumpCategory.java │ │ ├── CoreDumpConfigurator.java │ │ ├── CoreDumpDescriptorProvider.java │ │ ├── CoreDumpImpl.java │ │ ├── CoreDumpOverviewView.java │ │ ├── CoreDumpOverviewViewProvider.java │ │ ├── CoreDumpProvider.java │ │ └── OverviewViewSupport.java │ ├── package-info.java │ └── resources/ │ └── layer.xml ├── gotosource/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── gotosource/ │ ├── SourceHandle.java │ ├── SourceHandleProvider.java │ ├── SourceHandleUtils.java │ ├── SourcePathHandle.java │ ├── SourcesRoot.java │ ├── SourcesViewer.java │ ├── VisualVMGoToSource.java │ ├── arguments/ │ │ ├── Bundle.properties │ │ ├── SourceArguments.java │ │ ├── SourceConfigArgument.java │ │ ├── SourceRootsArgument.java │ │ └── SourceViewerArgument.java │ ├── impl/ │ │ ├── SourceHandles.java │ │ ├── SourceRoots.java │ │ └── SourceViewers.java │ ├── java/ │ │ ├── JavaClass.java │ │ ├── JavaMethod.java │ │ ├── JavaSourceHandle.java │ │ ├── JavaSourceHandleProvider.java │ │ └── JavaSourceUtils.java │ ├── options/ │ │ ├── SourcesOptions.java │ │ └── SourcesOptionsPanel.java │ ├── resources/ │ │ └── Bundle.properties │ ├── truffle/ │ │ ├── TruffleSourceHandle.java │ │ └── TruffleSourceHandleProvider.java │ └── viewer/ │ ├── ExternalSourcesViewer.java │ ├── ExternalViewerLauncher.java │ ├── RegisteredSourcesViewer.java │ └── internal/ │ ├── InternalSourceAppearance.java │ ├── InternalSourceViewerComponent.java │ ├── InternalSourceViewerTopComponent.java │ └── InternalSourcesViewer.java ├── graalvm/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── graalvm/ │ ├── Bundle.properties │ ├── Installer.java │ ├── application/ │ │ ├── descriptor/ │ │ │ ├── NativeImageApplicationDescriptor.java │ │ │ └── NativeImageApplicationDescriptorProvider.java │ │ └── type/ │ │ ├── Bundle.properties │ │ ├── GraalVMApplicationType.java │ │ └── GraalVMApplicationTypeFactory.java │ ├── libgraal/ │ │ ├── Bundle.properties │ │ ├── MemoryModel.java │ │ ├── MemorySnapshotViewPluginProvider.java │ │ ├── MemoryViewComponent.java │ │ ├── MemoryViewPlugin.java │ │ └── MemoryViewPluginProvider.java │ └── svm/ │ ├── SVMJVMImpl.java │ ├── SVMJvmProvider.java │ └── SVMMonitoredDataImpl.java ├── heapdump/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── heapdump/ │ ├── Bundle.properties │ ├── HeapDump.java │ ├── HeapDumpDescriptor.java │ ├── HeapDumpSupport.java │ ├── Installer.java │ ├── impl/ │ │ ├── Bundle.properties │ │ ├── HeapDumpAction.java │ │ ├── HeapDumpArgument.java │ │ ├── HeapDumpCategory.java │ │ ├── HeapDumpDescriptorProvider.java │ │ ├── HeapDumpImpl.java │ │ ├── HeapDumpOnOOMEAction.java │ │ ├── HeapDumpProvider.java │ │ ├── HeapDumpView.java │ │ └── HeapDumpViewProvider.java │ ├── package-info.java │ └── resources/ │ └── layer.xml ├── heapviewer/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── heapviewer/ │ ├── Bundle.properties │ ├── HeapContext.java │ ├── HeapFragment.java │ ├── HeapViewer.java │ ├── java/ │ │ ├── ClassNode.java │ │ ├── ClassNodeRenderer.java │ │ ├── ClassesContainer.java │ │ ├── InstanceNode.java │ │ ├── InstanceNodeRenderer.java │ │ ├── InstanceReferenceNode.java │ │ ├── InstanceReferenceNodeRenderer.java │ │ ├── InstancesContainer.java │ │ ├── InstancesWrapper.java │ │ ├── JavaGoToSourceAction.java │ │ ├── JavaHeapFragment.java │ │ ├── LocalObjectNode.java │ │ ├── LocalObjectNodeRenderer.java │ │ ├── PackageNodeRenderer.java │ │ ├── PrimitiveNode.java │ │ ├── PrimitiveNodeRenderer.java │ │ ├── StackFrameNode.java │ │ ├── StackFrameNodeRenderer.java │ │ ├── ThreadNode.java │ │ ├── ThreadNodeRenderer.java │ │ ├── ThreadStateNode.java │ │ ├── ThreadStateNodeRenderer.java │ │ └── impl/ │ │ ├── ClassHierarchyPlugin.java │ │ ├── EditableHistoryCombo.java │ │ ├── FilterUtils.java │ │ ├── GCTypeNode.java │ │ ├── HeapPatterns.java │ │ ├── JavaArrayItemsProvider.java │ │ ├── JavaClassesProvider.java │ │ ├── JavaDiffClassesProvider.java │ │ ├── JavaDiffDumpSelector.java │ │ ├── JavaDiffObjectsView.java │ │ ├── JavaFieldsPlugin.java │ │ ├── JavaFieldsProvider.java │ │ ├── JavaHeapFragmentProvider.java │ │ ├── JavaInstancesProvider.java │ │ ├── JavaNodesRendererProvider.java │ │ ├── JavaObjectView.java │ │ ├── JavaObjectsSummary.java │ │ ├── JavaObjectsView.java │ │ ├── JavaOpenNodeAction.java │ │ ├── JavaOverviewSummary.java │ │ ├── JavaPreviewPlugin.java │ │ ├── JavaReferencesPlugin.java │ │ ├── JavaReferencesProvider.java │ │ ├── JavaSummaryProvider.java │ │ ├── JavaSummaryView.java │ │ ├── JavaThreadsProvider.java │ │ ├── JavaThreadsSummary.java │ │ ├── JavaThreadsView.java │ │ ├── JavaWindowsView.java │ │ └── PathToGCRootPlugin.java │ ├── model/ │ │ ├── ContainerNode.java │ │ ├── DataType.java │ │ ├── ErrorNode.java │ │ ├── HeapViewerNode.java │ │ ├── HeapViewerNodeFilter.java │ │ ├── HeapViewerNodeWrapper.java │ │ ├── LoopNode.java │ │ ├── MoreNodesNode.java │ │ ├── NodesCache.java │ │ ├── Progress.java │ │ ├── ProgressNode.java │ │ ├── RootNode.java │ │ └── TextNode.java │ ├── options/ │ │ ├── HeapViewerOptionsCategory.java │ │ └── HeapViewerOptionsPanel.java │ ├── oql/ │ │ ├── CustomOQLQueries.java │ │ ├── EditableHistoryCombo.java │ │ ├── FilterUtils.java │ │ ├── OQLConsoleProvider.java │ │ ├── OQLConsoleView.java │ │ ├── OQLEditorComponent.java │ │ ├── OQLQueries.java │ │ ├── OQLQuery.java │ │ ├── OQLQueryCustomizer.java │ │ └── OQLQueryExecutor.java │ ├── swing/ │ │ ├── HTMLTextComponent.java │ │ ├── LinkButton.java │ │ ├── MenuButton.java │ │ ├── MultiSplitContainer.java │ │ └── Splitter.java │ ├── ui/ │ │ ├── BreadCrumbsNavigator.java │ │ ├── HTMLView.java │ │ ├── HeapDumpInfoAction.java │ │ ├── HeapView.java │ │ ├── HeapViewPlugin.java │ │ ├── HeapViewerActions.java │ │ ├── HeapViewerComponent.java │ │ ├── HeapViewerFeature.java │ │ ├── HeapViewerNodeAction.java │ │ ├── HeapViewerNumberRenderer.java │ │ ├── HeapViewerRenderer.java │ │ ├── HeapViewerRendererWrapper.java │ │ ├── HeapViewerTreeTable.java │ │ ├── MultiResolutionImageHack.java │ │ ├── NodeObjectsView.java │ │ ├── PluggableTreeTableView.java │ │ ├── SummaryView.java │ │ ├── TreeTableView.java │ │ ├── TreeTableViewColumn.java │ │ ├── TreeTableViewRenderer.java │ │ └── UIThresholds.java │ └── utils/ │ ├── ExcludingIterator.java │ ├── HeapOperations.java │ ├── HeapUtils.java │ ├── InterruptibleIterator.java │ ├── MoreObjectsNode.java │ ├── NodesComputer.java │ ├── ProgressIterator.java │ ├── SortedObjectsBuffer.java │ └── counters/ │ ├── BooleanCounter.java │ ├── ByteCounter.java │ ├── CharCounter.java │ ├── DoubleCounter.java │ ├── FloatCounter.java │ ├── InstanceCounter.java │ ├── IntCounter.java │ ├── LongCounter.java │ ├── PrimitiveCounter.java │ └── ShortCounter.java ├── heapviewer.console/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ ├── polyglot/ │ │ ├── Context.java │ │ ├── Value.java │ │ └── proxy/ │ │ └── ProxyArray.java │ └── visualvm/ │ └── heapviewer/ │ └── console/ │ ├── Bundle.properties │ └── r/ │ ├── CustomRQueries.java │ ├── MultiSplitContainer.java │ ├── RConsoleProvider.java │ ├── RConsoleView.java │ ├── REditorComponent.java │ ├── RPlotPanel.java │ ├── RQueries.java │ ├── RQueryCustomizer.java │ └── engine/ │ ├── ClassIDArray.java │ ├── ClassesArray.java │ ├── InstancesArray.java │ ├── InstancesSizeArray.java │ ├── NamesArray.java │ └── REngine.java ├── heapviewer.truffle/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── heapviewer/ │ └── truffle/ │ ├── Bundle.properties │ ├── TruffleFrame.java │ ├── TruffleInstancePropertyProvider.java │ ├── TruffleLanguage.java │ ├── TruffleLanguageHeapFragment.java │ ├── TruffleObject.java │ ├── TruffleObjectMergedFields.java │ ├── TruffleObjectMergedReferences.java │ ├── TruffleObjectPreviewPlugin.java │ ├── TruffleObjectPropertyPlugin.java │ ├── TruffleObjectPropertyProvider.java │ ├── TruffleObjectsProvider.java │ ├── TruffleObjectsWrapper.java │ ├── TruffleStackTraces.java │ ├── TruffleThreadsProvider.java │ ├── TruffleType.java │ ├── details/ │ │ ├── SourceDetailsProvider.java │ │ ├── SourceSectionView.java │ │ └── TruffleDetailsProvider.java │ ├── dynamicobject/ │ │ ├── DynamicObject.java │ │ ├── DynamicObjectArrayItemNode.java │ │ ├── DynamicObjectDetailsProvider.java │ │ ├── DynamicObjectFieldNode.java │ │ ├── DynamicObjectLanguageHeapFragment.java │ │ ├── DynamicObjectNode.java │ │ ├── DynamicObjectReferenceNode.java │ │ └── LocalDynamicObjectNode.java │ ├── javaext/ │ │ ├── TruffleFieldsProvider.java │ │ ├── TruffleJavaViewPlugin.java │ │ ├── TrufflePrimitiveArrayItemsProvider.java │ │ ├── TruffleReferencesProvider.java │ │ └── TruffleViewPlugin.java │ ├── lang/ │ │ ├── javascript/ │ │ │ ├── JavaScriptDetailsProvider.java │ │ │ ├── JavaScriptHeapFragment.java │ │ │ ├── JavaScriptLanguage.java │ │ │ ├── JavaScriptNodes.java │ │ │ ├── JavaScriptObject.java │ │ │ ├── JavaScriptObjectProperties.java │ │ │ ├── JavaScriptType.java │ │ │ ├── JavaScriptViewPlugins.java │ │ │ └── JavaScriptViews.java │ │ ├── python/ │ │ │ ├── PythonDetailsProvider.java │ │ │ ├── PythonHeapFragment.java │ │ │ ├── PythonLanguage.java │ │ │ ├── PythonNodes.java │ │ │ ├── PythonObject.java │ │ │ ├── PythonObjectProperties.java │ │ │ ├── PythonType.java │ │ │ ├── PythonViewPlugins.java │ │ │ └── PythonViews.java │ │ ├── r/ │ │ │ ├── RDetailsProvider.java │ │ │ ├── RHeapFragment.java │ │ │ ├── RLanguage.java │ │ │ ├── RNodes.java │ │ │ ├── RObject.java │ │ │ ├── RObjectProperties.java │ │ │ ├── RType.java │ │ │ ├── RViewPlugins.java │ │ │ └── RViews.java │ │ └── ruby/ │ │ ├── RubyDetailsProvider.java │ │ ├── RubyHeapFragment.java │ │ ├── RubyLanguage.java │ │ ├── RubyNodes.java │ │ ├── RubyObject.java │ │ ├── RubyObjectProperties.java │ │ ├── RubyType.java │ │ ├── RubyViewPlugins.java │ │ └── RubyViews.java │ ├── nodes/ │ │ ├── TerminalJavaNodes.java │ │ ├── TruffleLocalObjectNode.java │ │ ├── TruffleNodesRendererProvider.java │ │ ├── TruffleObjectArrayItemNode.java │ │ ├── TruffleObjectFieldNode.java │ │ ├── TruffleObjectNode.java │ │ ├── TruffleObjectReferenceNode.java │ │ ├── TruffleOpenNodeActionProvider.java │ │ ├── TruffleStackFrameNode.java │ │ └── TruffleTypeNode.java │ ├── swing/ │ │ ├── EditableHistoryCombo.java │ │ ├── LinkButton.java │ │ └── Splitter.java │ └── ui/ │ ├── FilterUtils.java │ ├── TruffleObjectView.java │ ├── TruffleObjectsView.java │ ├── TruffleSummaryView.java │ └── TruffleThreadsView.java ├── host/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── host/ │ ├── AddRemoteHostAction.java │ ├── Bundle.properties │ ├── Host.java │ ├── HostsSorting.java │ ├── HostsSupport.java │ ├── Installer.java │ ├── LocalHostDescriptor.java │ ├── RemoteHostDescriptor.java │ ├── RemoteHostsContainer.java │ ├── RemoteHostsContainerDescriptor.java │ ├── UnknownHostDescriptor.java │ ├── impl/ │ │ ├── Bundle.properties │ │ ├── GeneralPropertiesProvider.java │ │ ├── HostCustomizer.java │ │ ├── HostDescriptorProvider.java │ │ ├── HostProperties.java │ │ ├── HostProvider.java │ │ ├── HostsSupportImpl.java │ │ ├── LocalHostImpl.java │ │ ├── Ping.java │ │ └── RemoteHostImpl.java │ ├── model/ │ │ ├── HostOverview.java │ │ ├── HostOverviewFactory.java │ │ ├── LocalHostOverview.java │ │ └── package-info.java │ ├── package-info.java │ └── resources/ │ └── layer.xml ├── hostremote/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── host/ │ └── remote/ │ ├── Bundle.properties │ ├── Installer.java │ └── model/ │ ├── RemoteHostModelProvider.java │ └── RemoteHostOverview.java ├── hostviews/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── host/ │ └── views/ │ ├── Bundle.properties │ ├── HostViewsSupport.java │ ├── Installer.java │ ├── overview/ │ │ ├── Bundle.properties │ │ ├── HostOverviewView.java │ │ └── HostOverviewViewProvider.java │ └── package-info.java ├── jfr/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── jfr/ │ ├── Bundle.properties │ ├── Installer.java │ ├── JFRSnapshot.java │ ├── JFRSnapshotDescriptor.java │ ├── JFRSnapshotSupport.java │ ├── JFRSnapshotsContainer.java │ ├── JFRSnapshotsContainerDescriptor.java │ ├── JFRSnapshotsSorting.java │ ├── impl/ │ │ ├── AddJFRSnapshotAction.java │ │ ├── Bundle.properties │ │ ├── JFRArguments.java │ │ ├── JFRDumpAction.java │ │ ├── JFRDumpImpl.java │ │ ├── JFRParameters.java │ │ ├── JFRRecordingProvider.java │ │ ├── JFRSnapshotCategory.java │ │ ├── JFRSnapshotConfigurator.java │ │ ├── JFRSnapshotDescriptorProvider.java │ │ ├── JFRSnapshotImpl.java │ │ ├── JFRSnapshotProvider.java │ │ ├── JFRStartAction.java │ │ └── JFRStopAction.java │ ├── model/ │ │ ├── JFRClass.java │ │ ├── JFRDataDescriptor.java │ │ ├── JFREvent.java │ │ ├── JFREventChecker.java │ │ ├── JFREventType.java │ │ ├── JFREventTypeVisitor.java │ │ ├── JFREventVisitor.java │ │ ├── JFRMethod.java │ │ ├── JFRModel.java │ │ ├── JFRModelFactory.java │ │ ├── JFRModelProvider.java │ │ ├── JFRPropertyNotAvailableException.java │ │ ├── JFRStackFrame.java │ │ ├── JFRStackTrace.java │ │ ├── JFRThread.java │ │ └── impl/ │ │ ├── JfrModelImpl.java │ │ └── JfrModelProvider.java │ ├── resources/ │ │ └── layer.xml │ ├── utils/ │ │ ├── DurationFormatter.java │ │ ├── InstantFormatter.java │ │ ├── TimeRecord.java │ │ ├── ValuesChecker.java │ │ └── ValuesConverter.java │ ├── view/ │ │ ├── Bundle.properties │ │ ├── JFRView.java │ │ ├── JFRViewProvider.java │ │ ├── JFRViewTab.java │ │ └── JFRViewTabProvider.java │ └── views/ │ ├── browser/ │ │ ├── BrowserNode.java │ │ ├── BrowserRenderers.java │ │ ├── BrowserViewSupport.java │ │ ├── JFRSnapshotBrowserView.java │ │ └── JFRSnapshotBrowserViewProvider.java │ ├── components/ │ │ └── MessageComponent.java │ ├── environment/ │ │ ├── EnvironmentViewSupport.java │ │ ├── JFRSnapshotEnvironmentView.java │ │ └── JFRSnapshotEnvironmentViewProvider.java │ ├── exceptions/ │ │ ├── ExceptionsNode.java │ │ ├── ExceptionsRenderers.java │ │ ├── ExceptionsViewSupport.java │ │ ├── JFRSnapshotExceptionsView.java │ │ └── JFRSnapshotExceptionsViewProvider.java │ ├── fileio/ │ │ ├── FileIONode.java │ │ ├── FileIORenderers.java │ │ ├── FileIOViewSupport.java │ │ ├── JFRSnapshotFileIOView.java │ │ └── JFRSnapshotFileIOViewProvider.java │ ├── gc/ │ │ ├── GcNode.java │ │ ├── GcRenderers.java │ │ ├── GcViewSupport.java │ │ ├── JFRSnapshotGcView.java │ │ └── JFRSnapshotGcViewProvider.java │ ├── locks/ │ │ ├── JFRSnapshotLocksView.java │ │ ├── JFRSnapshotLocksViewProvider.java │ │ ├── LocksNode.java │ │ ├── LocksRenderers.java │ │ └── LocksViewSupport.java │ ├── monitor/ │ │ ├── Bundle.properties │ │ ├── JFRSnapshotMonitorView.java │ │ ├── JFRSnapshotMonitorViewProvider.java │ │ └── MonitorViewSupport.java │ ├── overview/ │ │ ├── Bundle.properties │ │ ├── JFRSnapshotOverviewView.java │ │ ├── JFRSnapshotOverviewViewProvider.java │ │ └── OverviewViewSupport.java │ ├── recording/ │ │ ├── Bundle.properties │ │ ├── JFRSnapshotRecordingView.java │ │ ├── JFRSnapshotRecordingViewProvider.java │ │ ├── RecordingNode.java │ │ ├── RecordingRenderers.java │ │ └── RecordingViewSupport.java │ ├── sampler/ │ │ ├── Bundle.properties │ │ ├── CPUSamplerViewSupport.java │ │ ├── JFRSnapshotSamplerView.java │ │ ├── JFRSnapshotSamplerViewProvider.java │ │ ├── JFRThreadInfoSupport.java │ │ ├── MemorySamplerViewSupport.java │ │ └── SamplerViewSupport.java │ ├── socketio/ │ │ ├── JFRSnapshotSocketIOView.java │ │ ├── JFRSnapshotSocketIOViewProvider.java │ │ ├── SocketIONode.java │ │ ├── SocketIORenderers.java │ │ └── SocketIOViewSupport.java │ └── threads/ │ ├── Bundle.properties │ ├── JFRSnapshotThreadsView.java │ ├── JFRSnapshotThreadsViewProvider.java │ ├── JFRThreadsDataManager.java │ └── ThreadsViewSupport.java ├── jfr.generic/ │ ├── build.xml │ ├── external/ │ │ ├── binaries-list │ │ ├── encoder-1.2.3-license.txt │ │ ├── flightrecorder-8.3.1-license.txt │ │ └── lz4-java-1.10.3-license.txt │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── jfr/ │ └── generic/ │ ├── Bundle.properties │ ├── Installer.java │ └── model/ │ └── impl/ │ ├── DisplayableSupport.java │ ├── JFRGenericClass.java │ ├── JFRGenericEvent.java │ ├── JFRGenericEventFactory.java │ ├── JFRGenericEventType.java │ ├── JFRGenericMethod.java │ ├── JFRGenericModel.java │ ├── JFRGenericModelProvider.java │ ├── JFRGenericStackFrame.java │ ├── JFRGenericStackTrace.java │ └── JFRGenericThread.java ├── jfr.jdk11/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── jfr/ │ └── jdk11/ │ ├── Bundle.properties │ ├── Installer.java │ └── model/ │ └── impl/ │ ├── DisplayableSupport.java │ ├── JFRJDK11Class.java │ ├── JFRJDK11Event.java │ ├── JFRJDK11EventType.java │ ├── JFRJDK11Method.java │ ├── JFRJDK11Model.java │ ├── JFRJDK11ModelProvider.java │ ├── JFRJDK11StackFrame.java │ ├── JFRJDK11StackTrace.java │ └── JFRJDK11Thread.java ├── jmx/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── jmx/ │ ├── Bundle.properties │ ├── CredentialsProvider.java │ ├── DefaultCustomizer.java │ ├── EnvironmentProvider.java │ ├── Installer.java │ ├── JmxApplicationException.java │ ├── JmxApplicationsSupport.java │ ├── JmxConnectionCustomizer.java │ ├── JmxConnectionSupport.java │ ├── impl/ │ │ ├── AddJMXConnectionAction.java │ │ ├── AutoConnectAction.java │ │ ├── Bundle.properties │ │ ├── ConnectDisconnectAction.java │ │ ├── CredentialsConfigurator.java │ │ ├── DisconnectedJmxModel.java │ │ ├── GeneralPropertiesProvider.java │ │ ├── HeapHistogramImpl.java │ │ ├── JmxApplication.java │ │ ├── JmxApplicationDescriptor.java │ │ ├── JmxApplicationDescriptorProvider.java │ │ ├── JmxApplicationProvider.java │ │ ├── JmxConnectionConfigurator.java │ │ ├── JmxConnectionSupportImpl.java │ │ ├── JmxHeartbeat.java │ │ ├── JmxModelImpl.java │ │ ├── JmxModelProvider.java │ │ ├── JmxPropertiesProvider.java │ │ ├── JmxSupport.java │ │ ├── OpenJmxApplication.java │ │ └── ProxyClient.java │ ├── package-info.java │ └── resources/ │ └── layer.xml ├── jvm/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── jvm/ │ ├── Bundle.properties │ ├── Installer.java │ ├── JRockitJVMImpl.java │ ├── JRockitJvmProvider.java │ ├── JVMImpl.java │ ├── JmxSupport.java │ ├── JvmProvider.java │ └── MonitoredDataImpl.java ├── jvmstat/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── jvmstat/ │ ├── Bundle.properties │ ├── Installer.java │ ├── JRockitJvmJvmstatModel.java │ ├── JRockitJvmJvmstatModelProvider.java │ ├── JvmJvmstatModelProvider.java │ ├── JvmJvmstatModel_25.java │ ├── JvmJvmstatModel_4.java │ ├── JvmJvmstatModel_5.java │ ├── JvmJvmstatModel_8.java │ ├── JvmstatModelImpl.java │ ├── JvmstatModelProvider.java │ ├── MonitoredValueImpl.java │ ├── OracleJRockitJvmJvmstatModel.java │ ├── OracleJRockitJvmJvmstatModelProvider.java │ ├── Utils.java │ ├── application/ │ │ ├── AddJstatdConnectionAction.java │ │ ├── Bundle.properties │ │ ├── ConnectionDescriptor.java │ │ ├── ConnectionsCustomizer.java │ │ ├── ConnectionsTable.java │ │ ├── GeneralPropertiesProvider.java │ │ ├── HostPropertiesProvider.java │ │ ├── JstatdPropertiesProvider.java │ │ ├── JvmstatApplication.java │ │ ├── JvmstatApplicationProvider.java │ │ └── PropertiesImpl.java │ └── resources/ │ └── layer.xml ├── killapp/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── modules/ │ └── killapp/ │ ├── Bundle.properties │ ├── KillAction.java │ └── layer.xml ├── launcher/ │ ├── visualvm │ ├── visualvm.conf │ ├── visualvm.icns │ ├── visualvm.import │ └── windows-src/ │ ├── Makefile │ ├── cmdargs.h │ ├── jvmfinder.cpp │ ├── jvmfinder.h │ ├── nbproject/ │ │ ├── Makefile-impl.mk │ │ ├── Makefile-variables.mk │ │ ├── Makefile-visualvm.exe.mk │ │ ├── Package-visualvm.exe.bash │ │ ├── configurations.xml │ │ ├── project.properties │ │ └── project.xml │ ├── o.n.bootstrap/ │ │ ├── argnames.h │ │ ├── nbexecloader.h │ │ ├── utilsfuncs.cpp │ │ └── utilsfuncs.h │ ├── version.h │ ├── version.rc │ ├── visualvm.cpp │ ├── visualvm.exe.manifest │ ├── visualvm.rc │ ├── visualvmlauncher.cpp │ └── visualvmlauncher.h ├── libs.profiler/ │ ├── lib.profiler/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── native/ │ │ │ ├── build/ │ │ │ │ ├── buildnative-linux-cvm.sh │ │ │ │ ├── buildnative-linux.sh │ │ │ │ ├── buildnative-linux64.sh │ │ │ │ ├── buildnative-linuxaarch64.sh │ │ │ │ ├── buildnative-linuxarm.sh │ │ │ │ ├── buildnative-mac-arm.sh │ │ │ │ ├── buildnative-mac.sh │ │ │ │ ├── buildnative-solaris-cvm.sh │ │ │ │ ├── buildnative-solaris.sh │ │ │ │ ├── buildnative-solaris64.sh │ │ │ │ ├── buildnative-windows-15.bat │ │ │ │ ├── buildnative-windows-16.bat │ │ │ │ ├── buildnative-windows-cvm-arm.bat │ │ │ │ ├── buildnative-windows-cvm.bat │ │ │ │ ├── buildnative-windows64-15.bat │ │ │ │ ├── buildnative-windows64-16.bat │ │ │ │ └── generate-headers-15.bat │ │ │ └── src-jdk15/ │ │ │ ├── Classes.c │ │ │ ├── GC.c │ │ │ ├── HeapDump.c │ │ │ ├── Stacks.c │ │ │ ├── Threads.c │ │ │ ├── Threads.h │ │ │ ├── Timers.c │ │ │ ├── attach.c │ │ │ ├── class_file_cache.c │ │ │ ├── common_functions.c │ │ │ ├── common_functions.h │ │ │ ├── org_graalvm_visualvm_lib_jfluid_server_system_Classes.h │ │ │ ├── org_graalvm_visualvm_lib_jfluid_server_system_Classes_RedefineException.h │ │ │ ├── org_graalvm_visualvm_lib_jfluid_server_system_GC.h │ │ │ ├── org_graalvm_visualvm_lib_jfluid_server_system_HeapDump.h │ │ │ ├── org_graalvm_visualvm_lib_jfluid_server_system_Stacks.h │ │ │ ├── org_graalvm_visualvm_lib_jfluid_server_system_Threads.h │ │ │ ├── org_graalvm_visualvm_lib_jfluid_server_system_Timers.h │ │ │ └── windows/ │ │ │ ├── version.h │ │ │ └── version.rc │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ ├── release/ │ │ │ └── lib/ │ │ │ └── deployed/ │ │ │ ├── jdk15/ │ │ │ │ └── mac/ │ │ │ │ └── libprofilerinterface.jnilib │ │ │ └── jdk16/ │ │ │ └── mac/ │ │ │ └── libprofilerinterface.jnilib │ │ ├── src/ │ │ │ ├── META-INF/ │ │ │ │ └── services/ │ │ │ │ ├── org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider │ │ │ │ ├── org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider$Listener │ │ │ │ ├── org.graalvm.visualvm.lib.jfluid.results.cpu.CPUProfilingResultListener │ │ │ │ ├── org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileBuilder │ │ │ │ ├── org.graalvm.visualvm.lib.jfluid.results.cpu.cct.CCTResultsFilter │ │ │ │ ├── org.graalvm.visualvm.lib.jfluid.results.cpu.cct.TimeCollector │ │ │ │ ├── org.graalvm.visualvm.lib.jfluid.results.cpu.marking.MarkingEngine$StateObserver │ │ │ │ ├── org.graalvm.visualvm.lib.jfluid.results.locks.LockProfilingResultListener │ │ │ │ ├── org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTProvider │ │ │ │ └── org.graalvm.visualvm.lib.jfluid.results.memory.MemoryProfilingResultsListener │ │ │ └── org/ │ │ │ └── graalvm/ │ │ │ └── visualvm/ │ │ │ └── lib/ │ │ │ └── jfluid/ │ │ │ ├── Bundle.properties │ │ │ ├── ProfilerClient.java │ │ │ ├── ProfilerClientListener.java │ │ │ ├── ProfilerEngineSettings.java │ │ │ ├── ProfilerLogger.java │ │ │ ├── ProfilingEventListener.java │ │ │ ├── TargetAppRunner.java │ │ │ ├── classfile/ │ │ │ │ ├── BaseClassInfo.java │ │ │ │ ├── Bundle.properties │ │ │ │ ├── ClassFileCache.java │ │ │ │ ├── ClassFileParser.java │ │ │ │ ├── ClassInfo.java │ │ │ │ ├── ClassLoaderTable.java │ │ │ │ ├── ClassPath.java │ │ │ │ ├── ClassRepository.java │ │ │ │ ├── DynamicClassInfo.java │ │ │ │ ├── LazyDynamicClassInfo.java │ │ │ │ ├── PlaceholderClassInfo.java │ │ │ │ └── SameNameClassGroup.java │ │ │ ├── client/ │ │ │ │ ├── AppStatusHandler.java │ │ │ │ ├── ClientUtils.java │ │ │ │ ├── MonitoredData.java │ │ │ │ ├── ProfilingPointsProcessor.java │ │ │ │ └── RuntimeProfilingPoint.java │ │ │ ├── filters/ │ │ │ │ ├── GenericFilter.java │ │ │ │ ├── InstrumentationFilter.java │ │ │ │ ├── JavaTypeFilter.java │ │ │ │ └── TextFilter.java │ │ │ ├── global/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── CalibrationDataFileIO.java │ │ │ │ ├── CommonConstants.java │ │ │ │ ├── Platform.java │ │ │ │ ├── ProfilingSessionStatus.java │ │ │ │ └── TransactionalSupport.java │ │ │ ├── instrumentation/ │ │ │ │ ├── BadLocationException.java │ │ │ │ ├── Bundle.properties │ │ │ │ ├── CPExtensionsRepository.java │ │ │ │ ├── ClassManager.java │ │ │ │ ├── ClassRewriter.java │ │ │ │ ├── CodeRegionEntryExitCallsInjector.java │ │ │ │ ├── CodeRegionMethodInstrumentor.java │ │ │ │ ├── ConstantPoolExtension.java │ │ │ │ ├── DynamicConstantPoolExtension.java │ │ │ │ ├── HandleReflectInvokeCallInjector.java │ │ │ │ ├── HandleServletDoMethodCallInjector.java │ │ │ │ ├── Injector.java │ │ │ │ ├── InstrumentationException.java │ │ │ │ ├── InstrumentationFactory.java │ │ │ │ ├── Instrumentor.java │ │ │ │ ├── JavaClassConstants.java │ │ │ │ ├── MemoryProfMethodInstrumentor.java │ │ │ │ ├── MethodEntryExitCallsInjector.java │ │ │ │ ├── MiscInstrumentationOps.java │ │ │ │ ├── ObjLivenessInstrCallsInjector.java │ │ │ │ ├── ObjLivenessMethodInstrumentor.java │ │ │ │ ├── ProfilePointHitCallInjector.java │ │ │ │ ├── RecursiveMethodInstrumentor.java │ │ │ │ ├── RecursiveMethodInstrumentor1.java │ │ │ │ ├── RecursiveMethodInstrumentor2.java │ │ │ │ ├── RecursiveMethodInstrumentor3.java │ │ │ │ ├── RootMethods.java │ │ │ │ ├── SingleMethodScaner.java │ │ │ │ └── SpecialCallInjector.java │ │ │ ├── jps/ │ │ │ │ ├── JpsProxy.java │ │ │ │ └── RunningVM.java │ │ │ ├── marker/ │ │ │ │ ├── ClassMarker.java │ │ │ │ ├── CompositeMarker.java │ │ │ │ ├── Mark.java │ │ │ │ ├── Marker.java │ │ │ │ ├── MethodMarker.java │ │ │ │ └── PackageMarker.java │ │ │ ├── results/ │ │ │ │ ├── AbstractDataFrameProcessor.java │ │ │ │ ├── BaseCallGraphBuilder.java │ │ │ │ ├── Bundle.properties │ │ │ │ ├── CCTNode.java │ │ │ │ ├── CCTProvider.java │ │ │ │ ├── DataFrameProcessor.java │ │ │ │ ├── DataManager.java │ │ │ │ ├── DataManagerListener.java │ │ │ │ ├── EventBufferProcessor.java │ │ │ │ ├── EventBufferResultsProvider.java │ │ │ │ ├── ExportDataDumper.java │ │ │ │ ├── FilterSortSupport.java │ │ │ │ ├── ProfilingResultListener.java │ │ │ │ ├── ProfilingResultsDispatcher.java │ │ │ │ ├── ProfilingResultsProvider.java │ │ │ │ ├── ResultsSnapshot.java │ │ │ │ ├── RuntimeCCTNode.java │ │ │ │ ├── RuntimeCCTNodeProcessor.java │ │ │ │ ├── coderegion/ │ │ │ │ │ ├── Bundle.properties │ │ │ │ │ └── CodeRegionResultsSnapshot.java │ │ │ │ ├── cpu/ │ │ │ │ │ ├── AllThreadsMergedCPUCCTContainer.java │ │ │ │ │ ├── Bundle.properties │ │ │ │ │ ├── CPUCCTClassContainer.java │ │ │ │ │ ├── CPUCCTContainer.java │ │ │ │ │ ├── CPUCCTProvider.java │ │ │ │ │ ├── CPUCallGraphBuilder.java │ │ │ │ │ ├── CPUDataFrameProcessor.java │ │ │ │ │ ├── CPUProfilingResultListener.java │ │ │ │ │ ├── CPUResultsDiff.java │ │ │ │ │ ├── CPUResultsSnapshot.java │ │ │ │ │ ├── CPUSamplingDataFrameProcessor.java │ │ │ │ │ ├── DiffCPUCCTNode.java │ │ │ │ │ ├── DiffFlatProfileContainer.java │ │ │ │ │ ├── FlatProfileBuilder.java │ │ │ │ │ ├── FlatProfileContainer.java │ │ │ │ │ ├── FlatProfileContainerBacked.java │ │ │ │ │ ├── FlatProfileContainerFree.java │ │ │ │ │ ├── FlatProfileProvider.java │ │ │ │ │ ├── InstrTimingData.java │ │ │ │ │ ├── MethodIdMap.java │ │ │ │ │ ├── MethodInfoMapper.java │ │ │ │ │ ├── PrestimeCPUCCTNode.java │ │ │ │ │ ├── PrestimeCPUCCTNodeBacked.java │ │ │ │ │ ├── PrestimeCPUCCTNodeFree.java │ │ │ │ │ ├── StackTraceSnapshotBuilder.java │ │ │ │ │ ├── ThreadInfo.java │ │ │ │ │ ├── ThreadInfos.java │ │ │ │ │ ├── TimingAdjuster.java │ │ │ │ │ ├── TimingAdjusterOld.java │ │ │ │ │ ├── cct/ │ │ │ │ │ │ ├── CCTFlattener.java │ │ │ │ │ │ ├── CCTResultsFilter.java │ │ │ │ │ │ ├── TimeCollector.java │ │ │ │ │ │ └── nodes/ │ │ │ │ │ │ ├── BaseCPUCCTNode.java │ │ │ │ │ │ ├── MarkedCPUCCTNode.java │ │ │ │ │ │ ├── MethodCPUCCTNode.java │ │ │ │ │ │ ├── RuntimeCPUCCTNode.java │ │ │ │ │ │ ├── ServletRequestCPUCCTNode.java │ │ │ │ │ │ ├── SimpleCPUCCTNode.java │ │ │ │ │ │ ├── ThreadCPUCCTNode.java │ │ │ │ │ │ └── TimedCPUCCTNode.java │ │ │ │ │ └── marking/ │ │ │ │ │ ├── MarkAwareNodeProcessorPlugin.java │ │ │ │ │ ├── MarkMapper.java │ │ │ │ │ ├── MarkMapping.java │ │ │ │ │ └── MarkingEngine.java │ │ │ │ ├── jdbc/ │ │ │ │ │ ├── JdbcCCTProvider.java │ │ │ │ │ ├── JdbcGraphBuilder.java │ │ │ │ │ ├── JdbcResultsDiff.java │ │ │ │ │ ├── JdbcResultsSnapshot.java │ │ │ │ │ ├── SQLConnection.java │ │ │ │ │ ├── SQLParser.java │ │ │ │ │ ├── SQLStatement.java │ │ │ │ │ └── StringCache.java │ │ │ │ ├── locks/ │ │ │ │ │ ├── AbstractLockDataFrameProcessor.java │ │ │ │ │ ├── Bundle.properties │ │ │ │ │ ├── LockCCTNode.java │ │ │ │ │ ├── LockCCTProvider.java │ │ │ │ │ ├── LockDataFrameProcessor.java │ │ │ │ │ ├── LockGraphBuilder.java │ │ │ │ │ ├── LockProfilingResultListener.java │ │ │ │ │ ├── LockRuntimeCCTNode.java │ │ │ │ │ ├── MonitorCCTNode.java │ │ │ │ │ ├── MonitorInfo.java │ │ │ │ │ ├── ThreadInfo.java │ │ │ │ │ ├── ThreadInfos.java │ │ │ │ │ ├── ThreadLockCCTNode.java │ │ │ │ │ └── TopLockCCTNode.java │ │ │ │ ├── memory/ │ │ │ │ │ ├── AllocMemoryResultsDiff.java │ │ │ │ │ ├── AllocMemoryResultsSnapshot.java │ │ │ │ │ ├── Bundle.properties │ │ │ │ │ ├── ClassHistoryDataManager.java │ │ │ │ │ ├── DiffObjAllocCCTNode.java │ │ │ │ │ ├── DiffObjLivenessCCTNode.java │ │ │ │ │ ├── HeapHistogram.java │ │ │ │ │ ├── HeapHistogramManager.java │ │ │ │ │ ├── JMethodIdTable.java │ │ │ │ │ ├── LivenessMemoryResultsDiff.java │ │ │ │ │ ├── LivenessMemoryResultsSnapshot.java │ │ │ │ │ ├── MemoryCCTManager.java │ │ │ │ │ ├── MemoryCCTProvider.java │ │ │ │ │ ├── MemoryCallGraphBuilder.java │ │ │ │ │ ├── MemoryDataFrameProcessor.java │ │ │ │ │ ├── MemoryProfilingResultsListener.java │ │ │ │ │ ├── MemoryResultsSnapshot.java │ │ │ │ │ ├── PresoObjAllocCCTNode.java │ │ │ │ │ ├── PresoObjLivenessCCTNode.java │ │ │ │ │ ├── RuntimeMemoryCCTNode.java │ │ │ │ │ ├── RuntimeObjAllocTermCCTNode.java │ │ │ │ │ ├── RuntimeObjLivenessTermCCTNode.java │ │ │ │ │ ├── SampledMemoryResultsDiff.java │ │ │ │ │ ├── SampledMemoryResultsSnapshot.java │ │ │ │ │ └── SurvGenSet.java │ │ │ │ ├── monitor/ │ │ │ │ │ └── VMTelemetryDataManager.java │ │ │ │ └── threads/ │ │ │ │ ├── ThreadData.java │ │ │ │ ├── ThreadDump.java │ │ │ │ └── ThreadsDataManager.java │ │ │ ├── server/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── ClassBytesLoader.java │ │ │ │ ├── ClassLoaderManager.java │ │ │ │ ├── EventBufferManager.java │ │ │ │ ├── HeapHistogramManager.java │ │ │ │ ├── InstrumentConstructorTest.java │ │ │ │ ├── Monitors.java │ │ │ │ ├── ProfilerAPI.java │ │ │ │ ├── ProfilerCalibrator.java │ │ │ │ ├── ProfilerInterface.java │ │ │ │ ├── ProfilerRuntime.java │ │ │ │ ├── ProfilerRuntimeCPU.java │ │ │ │ ├── ProfilerRuntimeCPUCodeRegion.java │ │ │ │ ├── ProfilerRuntimeCPUFullInstr.java │ │ │ │ ├── ProfilerRuntimeCPUSampledInstr.java │ │ │ │ ├── ProfilerRuntimeMemory.java │ │ │ │ ├── ProfilerRuntimeObjAlloc.java │ │ │ │ ├── ProfilerRuntimeObjLiveness.java │ │ │ │ ├── ProfilerRuntimeSampler.java │ │ │ │ ├── ProfilerServer.java │ │ │ │ ├── ProfilingPointServerHandler.java │ │ │ │ ├── ResetResultsProfilingPointHandler.java │ │ │ │ ├── SamplingThread.java │ │ │ │ ├── StartProfilingPointHandler.java │ │ │ │ ├── StopProfilingPointHandler.java │ │ │ │ ├── TakeHeapdumpProfilingPointHandler.java │ │ │ │ ├── TakeSnapshotProfilingPointHandler.java │ │ │ │ ├── TakeSnapshotWithResetProfilingPointHandler.java │ │ │ │ ├── ThreadInfo.java │ │ │ │ └── system/ │ │ │ │ ├── GC.java │ │ │ │ ├── Stacks.java │ │ │ │ └── Threads.java │ │ │ ├── utils/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── FileOrZipEntry.java │ │ │ │ ├── FloatSorter.java │ │ │ │ ├── IntSorter.java │ │ │ │ ├── IntVector.java │ │ │ │ ├── LongSorter.java │ │ │ │ ├── MiscUtils.java │ │ │ │ ├── StringSorter.java │ │ │ │ ├── StringUtils.java │ │ │ │ ├── VMUtils.java │ │ │ │ ├── Wildcards.java │ │ │ │ └── formatting/ │ │ │ │ ├── DefaultMethodNameFormatter.java │ │ │ │ ├── Formattable.java │ │ │ │ ├── MethodNameFormatter.java │ │ │ │ ├── MethodNameFormatterFactory.java │ │ │ │ └── PlainFormattableMethodName.java │ │ │ └── wireprotocol/ │ │ │ ├── AsyncMessageCommand.java │ │ │ ├── Bundle.properties │ │ │ ├── CalibrationDataResponse.java │ │ │ ├── ClassLoadedCommand.java │ │ │ ├── CodeRegionCPUResultsResponse.java │ │ │ ├── Command.java │ │ │ ├── DefiningLoaderResponse.java │ │ │ ├── DumpResultsResponse.java │ │ │ ├── EventBufferDumpedCommand.java │ │ │ ├── GetClassFileBytesCommand.java │ │ │ ├── GetClassFileBytesResponse.java │ │ │ ├── GetClassIdCommand.java │ │ │ ├── GetClassIdResponse.java │ │ │ ├── GetDefiningClassLoaderCommand.java │ │ │ ├── GetMethodNamesForJMethodIdsCommand.java │ │ │ ├── HeapHistogramResponse.java │ │ │ ├── InitiateProfilingCommand.java │ │ │ ├── InstrumentMethodGroupCommand.java │ │ │ ├── InstrumentMethodGroupData.java │ │ │ ├── InstrumentMethodGroupResponse.java │ │ │ ├── InternalStatsResponse.java │ │ │ ├── MethodInvokedFirstTimeCommand.java │ │ │ ├── MethodLoadedCommand.java │ │ │ ├── MethodNamesResponse.java │ │ │ ├── MonitoredNumbersResponse.java │ │ │ ├── ObjectAllocationResultsResponse.java │ │ │ ├── Response.java │ │ │ ├── RootClassLoadedCommand.java │ │ │ ├── SetChangeableInstrParamsCommand.java │ │ │ ├── SetUnchangeableInstrParamsCommand.java │ │ │ ├── TakeHeapDumpCommand.java │ │ │ ├── ThreadDumpResponse.java │ │ │ ├── ThreadLivenessStatusResponse.java │ │ │ ├── VMPropertiesResponse.java │ │ │ └── WireIO.java │ │ ├── src-cvm/ │ │ │ ├── manifest.mf │ │ │ └── org/ │ │ │ └── graalvm/ │ │ │ └── visualvm/ │ │ │ └── lib/ │ │ │ └── jfluid/ │ │ │ └── server/ │ │ │ └── system/ │ │ │ ├── Classes.java │ │ │ ├── HeapDump.java │ │ │ ├── Histogram.java │ │ │ ├── ThreadDump.java │ │ │ └── Timers.java │ │ ├── src-jdk15/ │ │ │ ├── manifest.mf │ │ │ └── org/ │ │ │ └── graalvm/ │ │ │ └── visualvm/ │ │ │ └── lib/ │ │ │ └── jfluid/ │ │ │ └── server/ │ │ │ ├── ProfilerActivate15.java │ │ │ └── system/ │ │ │ ├── Classes.java │ │ │ ├── HeapDump.java │ │ │ ├── Histogram.java │ │ │ ├── Histogram18.java │ │ │ ├── Histogram19.java │ │ │ ├── ThreadDump.java │ │ │ └── Timers.java │ │ └── test/ │ │ ├── functional/ │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── graalvm/ │ │ │ └── visualvm/ │ │ │ └── lib/ │ │ │ └── jfluid/ │ │ │ └── tests/ │ │ │ └── jfluid/ │ │ │ └── perf/ │ │ │ └── InstrumentationTest.java │ │ ├── lib/ │ │ │ └── tests-functional.jar │ │ ├── qa-functional/ │ │ │ ├── coverage.txt │ │ │ ├── data/ │ │ │ │ ├── goldenfiles/ │ │ │ │ │ └── org/ │ │ │ │ │ └── graalvm/ │ │ │ │ │ └── visualvm/ │ │ │ │ │ └── lib/ │ │ │ │ │ └── jfluid/ │ │ │ │ │ └── tests/ │ │ │ │ │ └── jfluid/ │ │ │ │ │ ├── cpu/ │ │ │ │ │ │ ├── BasicTest/ │ │ │ │ │ │ │ ├── testMethodWithWaitEager.pass │ │ │ │ │ │ │ ├── testMethodWithWaitEagerServer.pass │ │ │ │ │ │ │ ├── testMethodWithWaitExcludeWEager.pass │ │ │ │ │ │ │ ├── testMethodWithWaitExcludeWLazy.pass │ │ │ │ │ │ │ ├── testMethodWithWaitExcludeWTotal.pass │ │ │ │ │ │ │ ├── testMethodWithWaitLazy.pass │ │ │ │ │ │ │ ├── testMethodWithWaitLazyServer.pass │ │ │ │ │ │ │ ├── testMethodWithWaitTotal.pass │ │ │ │ │ │ │ ├── testMethodWithWaitTotalServer.pass │ │ │ │ │ │ │ ├── testSettingsDefault.pass │ │ │ │ │ │ │ ├── testSettingsInstrumenManyMethodsLazy.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentAllEager.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentAllEagerServer.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentAllLazy.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentAllLazyServer.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentAllTotal.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentAllTotalServer.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentExcludeJavas.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentExcludeJavasServer.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentManyMethodsEager.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentManyMethodsTotal.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentNotSpawnedThreads.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentNotSpawnedThreadsServer.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentRootMethod.pass │ │ │ │ │ │ │ ├── testSettingsInstrumentRootMethodServer.pass │ │ │ │ │ │ │ ├── testSettingsLimitedThreads.pass │ │ │ │ │ │ │ ├── testSettingsLimitedThreadsServer.pass │ │ │ │ │ │ │ ├── testSettingsSampledProfilingEager.pass │ │ │ │ │ │ │ ├── testSettingsSampledProfilingLazy.pass │ │ │ │ │ │ │ ├── testSettingsSampledProfilingServerEager.pass │ │ │ │ │ │ │ ├── testSettingsSampledProfilingServerLazy.pass │ │ │ │ │ │ │ ├── testSettingsSampledProfilingServerTotal.pass │ │ │ │ │ │ │ └── testSettingsSampledProfilingTotal.pass │ │ │ │ │ │ └── CPUSnapshotTest/ │ │ │ │ │ │ ├── testMethods.pass │ │ │ │ │ │ ├── testMethodsServer.pass │ │ │ │ │ │ ├── testNoThreads.pass │ │ │ │ │ │ ├── testSimple.pass │ │ │ │ │ │ ├── testSimpleServer.pass │ │ │ │ │ │ ├── testThreads.pass │ │ │ │ │ │ ├── testThreadsServer.pass │ │ │ │ │ │ ├── testWaits.pass │ │ │ │ │ │ └── testWaitsServer.pass │ │ │ │ │ ├── memory/ │ │ │ │ │ │ ├── BasicTest/ │ │ │ │ │ │ │ ├── testSettingsAllocations.pass │ │ │ │ │ │ │ ├── testSettingsAllocationsServer.pass │ │ │ │ │ │ │ ├── testSettingsAllocationsStackTraces.pass │ │ │ │ │ │ │ ├── testSettingsAllocationsStackTracesServer.pass │ │ │ │ │ │ │ ├── testSettingsDefault.pass │ │ │ │ │ │ │ ├── testSettingsLiveness.pass │ │ │ │ │ │ │ ├── testSettingsLivenessServer.pass │ │ │ │ │ │ │ ├── testSettingsLivenessStackTraces.pass │ │ │ │ │ │ │ └── testSettingsLivenessStackTracesServer.pass │ │ │ │ │ │ └── MemorySnapshotTest/ │ │ │ │ │ │ ├── testSettingsAllocations.pass │ │ │ │ │ │ ├── testSettingsAllocationsServer.pass │ │ │ │ │ │ ├── testSettingsAllocationsStackTraces.pass │ │ │ │ │ │ ├── testSettingsAllocationsStackTracesServer.pass │ │ │ │ │ │ ├── testSettingsLiveness.pass │ │ │ │ │ │ ├── testSettingsLivenessServer.pass │ │ │ │ │ │ ├── testSettingsLivenessStackTraces.pass │ │ │ │ │ │ └── testSettingsLivenessStackTracesServer.pass │ │ │ │ │ ├── monitor/ │ │ │ │ │ │ └── BasicTest/ │ │ │ │ │ │ ├── testBasic.pass │ │ │ │ │ │ ├── testBasicCPU.pass │ │ │ │ │ │ ├── testBasicMemory.pass │ │ │ │ │ │ ├── testCascadeThreads.pass │ │ │ │ │ │ ├── testCascadeThreadsCPU.pass │ │ │ │ │ │ ├── testCascadeThreadsMemory.pass │ │ │ │ │ │ └── testGUICPU.pass │ │ │ │ │ ├── perf/ │ │ │ │ │ │ └── InstrumentationTest/ │ │ │ │ │ │ ├── testJ2SE.pass │ │ │ │ │ │ ├── testJaxb.pass │ │ │ │ │ │ ├── testJaxbNoGettersEmpties.pass │ │ │ │ │ │ ├── testSimple.pass │ │ │ │ │ │ ├── testSimpleJ2SE.pass │ │ │ │ │ │ ├── testSimpleNoEmpties.pass │ │ │ │ │ │ └── testSimpleNoGetters.pass │ │ │ │ │ ├── profilingpoints/ │ │ │ │ │ │ └── BasicTest/ │ │ │ │ │ │ ├── testEmpytBlock.pass │ │ │ │ │ │ ├── testFirstEmptyLineEndMethod.pass │ │ │ │ │ │ ├── testLinesCodeEmptyBlockEmptyLine.pass │ │ │ │ │ │ ├── testLinesWithWait.pass │ │ │ │ │ │ ├── testSimpleBlock.pass │ │ │ │ │ │ ├── testSimpleBlockServer.pass │ │ │ │ │ │ ├── testStartMethodMultiCommands.pass │ │ │ │ │ │ └── testWholeMethod.pass │ │ │ │ │ └── wireio/ │ │ │ │ │ └── BasicTest/ │ │ │ │ │ ├── testComplexCommands.pass │ │ │ │ │ ├── testComplexResponse.pass │ │ │ │ │ ├── testSimpleCommands.pass │ │ │ │ │ ├── testSimpleResponse.pass │ │ │ │ │ └── testUnknownSimpleCommand.pass │ │ │ │ ├── perfdata/ │ │ │ │ │ ├── j2se-simple.jar │ │ │ │ │ ├── jaxb-xjc.jar │ │ │ │ │ └── oneclass.jar │ │ │ │ └── projects/ │ │ │ │ ├── j2se-simple/ │ │ │ │ │ ├── build-before-profiler.xml │ │ │ │ │ ├── build.xml │ │ │ │ │ ├── distrib/ │ │ │ │ │ │ └── j2se-simple.jar │ │ │ │ │ ├── nbproject/ │ │ │ │ │ │ ├── build-impl.xml │ │ │ │ │ │ ├── genfiles.properties │ │ │ │ │ │ ├── profiler-build-impl.xml │ │ │ │ │ │ ├── project.properties │ │ │ │ │ │ └── project.xml │ │ │ │ │ └── src/ │ │ │ │ │ └── simple/ │ │ │ │ │ ├── CPU.java │ │ │ │ │ ├── Consumer.java │ │ │ │ │ ├── Data.java │ │ │ │ │ ├── Memory.java │ │ │ │ │ ├── Monitor.java │ │ │ │ │ ├── Producer.java │ │ │ │ │ ├── cpu/ │ │ │ │ │ │ ├── AnotherThread.java │ │ │ │ │ │ ├── Bean.java │ │ │ │ │ │ ├── CPU1.java │ │ │ │ │ │ ├── CPUThread.java │ │ │ │ │ │ ├── Measure.java │ │ │ │ │ │ ├── Methods.java │ │ │ │ │ │ ├── Methods2.java │ │ │ │ │ │ ├── Region.java │ │ │ │ │ │ └── WaitingTest.java │ │ │ │ │ ├── memory/ │ │ │ │ │ │ ├── Bean.java │ │ │ │ │ │ └── Memory1.java │ │ │ │ │ └── monitor/ │ │ │ │ │ ├── CascadeThread.java │ │ │ │ │ └── Monitor1.java │ │ │ │ └── jbb/ │ │ │ │ ├── config.properties │ │ │ │ ├── distrib/ │ │ │ │ │ └── jbb.jar │ │ │ │ └── xml/ │ │ │ │ ├── jbb-document.dtd │ │ │ │ └── template-document.xml │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── graalvm/ │ │ │ └── visualvm/ │ │ │ └── lib/ │ │ │ └── jfluid/ │ │ │ └── tests/ │ │ │ └── jfluid/ │ │ │ ├── BasicTest.java │ │ │ ├── CommonProfilerTestCase.java │ │ │ ├── ProfilerStableTestSuite.java │ │ │ ├── benchmarks/ │ │ │ │ ├── JbbTest.java │ │ │ │ └── JbbTestType.java │ │ │ ├── cpu/ │ │ │ │ ├── BasicTest.java │ │ │ │ ├── CPUSnapshotTest.java │ │ │ │ ├── CPUSnapshotTestCase.java │ │ │ │ └── CPUTestCase.java │ │ │ ├── memory/ │ │ │ │ ├── BasicTest.java │ │ │ │ ├── MemorySnapshotTest.java │ │ │ │ ├── MemorySnapshotTestCase.java │ │ │ │ └── MemoryTestCase.java │ │ │ ├── monitor/ │ │ │ │ ├── BasicTest.java │ │ │ │ └── MonitorTestCase.java │ │ │ ├── others/ │ │ │ │ ├── MeasureDiffsTest.java │ │ │ │ └── MeasureDiffsTestCase.java │ │ │ ├── perf/ │ │ │ │ └── InstrumentationTest.java │ │ │ ├── profilingpoints/ │ │ │ │ ├── BasicTest.java │ │ │ │ └── ProfilingPointsTestCase.java │ │ │ ├── utils/ │ │ │ │ ├── DumpStream.java │ │ │ │ ├── TestAsyncDialog.java │ │ │ │ ├── TestProfilerAppHandler.java │ │ │ │ ├── TestProfilingPointsProcessor.java │ │ │ │ └── Utils.java │ │ │ └── wireio/ │ │ │ ├── BasicTest.java │ │ │ └── CommonWireIOTestCase.java │ │ └── unit/ │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── jfluid/ │ │ ├── results/ │ │ │ └── cpu/ │ │ │ └── StackTraceSnapshotBuilderTest.java │ │ └── utils/ │ │ ├── VMUtilsTest.java │ │ └── formatting/ │ │ └── PlainFormattableMethodNameTest.java │ ├── lib.profiler.charts/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── charts/ │ │ ├── Bundle.properties │ │ ├── ChartComponent.java │ │ ├── ChartConfigurationListener.java │ │ ├── ChartContext.java │ │ ├── ChartDecorator.java │ │ ├── ChartItem.java │ │ ├── ChartItemChange.java │ │ ├── ChartItemListener.java │ │ ├── ChartOverlay.java │ │ ├── ChartSelectionListener.java │ │ ├── ChartSelectionManager.java │ │ ├── ChartSelectionModel.java │ │ ├── CompoundItemPainter.java │ │ ├── ItemPainter.java │ │ ├── ItemSelection.java │ │ ├── ItemsListener.java │ │ ├── ItemsModel.java │ │ ├── PaintersListener.java │ │ ├── PaintersModel.java │ │ ├── Timeline.java │ │ ├── axis/ │ │ │ ├── AxisComponent.java │ │ │ ├── AxisMark.java │ │ │ ├── AxisMarksComputer.java │ │ │ ├── AxisMarksPainter.java │ │ │ ├── BitsPerSecMarksPainter.java │ │ │ ├── Bundle.properties │ │ │ ├── BytesAxisUtils.java │ │ │ ├── BytesMark.java │ │ │ ├── BytesMarksPainter.java │ │ │ ├── DecimalAxisUtils.java │ │ │ ├── LongMark.java │ │ │ ├── PercentLongMarksPainter.java │ │ │ ├── SimpleLongMarksPainter.java │ │ │ ├── TimeAxisUtils.java │ │ │ ├── TimeMark.java │ │ │ ├── TimeMarksPainter.java │ │ │ └── TimelineMarksComputer.java │ │ ├── canvas/ │ │ │ ├── BufferedCanvasComponent.java │ │ │ ├── InteractiveCanvasComponent.java │ │ │ └── TransformableCanvasComponent.java │ │ ├── swing/ │ │ │ ├── CrossBorderLayout.java │ │ │ ├── LongRect.java │ │ │ ├── RoundBorder.java │ │ │ └── Utils.java │ │ └── xy/ │ │ ├── BytesXYItemMarksComputer.java │ │ ├── CompoundXYItemPainter.java │ │ ├── DecimalXYItemMarksComputer.java │ │ ├── XYItem.java │ │ ├── XYItemChange.java │ │ ├── XYItemMarksComputer.java │ │ ├── XYItemPainter.java │ │ ├── XYItemSelection.java │ │ └── synchronous/ │ │ ├── SynchronousXYChart.java │ │ ├── SynchronousXYChartContext.java │ │ ├── SynchronousXYItem.java │ │ ├── SynchronousXYItemMarker.java │ │ ├── SynchronousXYItemPainter.java │ │ └── SynchronousXYItemsModel.java │ ├── lib.profiler.common/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── common/ │ │ ├── AttachSettings.java │ │ ├── Bundle.properties │ │ ├── CommonUtils.java │ │ ├── GlobalProfilingSettings.java │ │ ├── Profiler.java │ │ ├── ProfilingSettings.java │ │ ├── ProfilingSettingsPresets.java │ │ ├── SessionSettings.java │ │ ├── event/ │ │ │ ├── ProfilingStateAdapter.java │ │ │ ├── ProfilingStateEvent.java │ │ │ ├── ProfilingStateListener.java │ │ │ └── SimpleProfilingStateAdapter.java │ │ └── integration/ │ │ ├── Bundle.properties │ │ └── IntegrationUtils.java │ ├── lib.profiler.heap/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ ├── src/ │ │ │ └── org/ │ │ │ └── graalvm/ │ │ │ └── visualvm/ │ │ │ └── lib/ │ │ │ └── jfluid/ │ │ │ └── heap/ │ │ │ ├── AbstractLongMap.java │ │ │ ├── ArrayDump.java │ │ │ ├── ArrayItemValue.java │ │ │ ├── Bundle.properties │ │ │ ├── CacheDirectory.java │ │ │ ├── ClassDump.java │ │ │ ├── ClassDumpInstance.java │ │ │ ├── ClassDumpSegment.java │ │ │ ├── ClassLoaderFieldValue.java │ │ │ ├── ComputedSummary.java │ │ │ ├── DominatorTree.java │ │ │ ├── Field.java │ │ │ ├── FieldValue.java │ │ │ ├── GCRoot.java │ │ │ ├── Heap.java │ │ │ ├── HeapFactory.java │ │ │ ├── HeapProgress.java │ │ │ ├── HeapSummary.java │ │ │ ├── HprofArrayValue.java │ │ │ ├── HprofByteBuffer.java │ │ │ ├── HprofField.java │ │ │ ├── HprofFieldObjectValue.java │ │ │ ├── HprofFieldValue.java │ │ │ ├── HprofFileBuffer.java │ │ │ ├── HprofGCRoot.java │ │ │ ├── HprofGCRoots.java │ │ │ ├── HprofHeap.java │ │ │ ├── HprofInstanceObjectValue.java │ │ │ ├── HprofInstanceValue.java │ │ │ ├── HprofLongMappedByteBuffer.java │ │ │ ├── HprofMappedByteBuffer.java │ │ │ ├── HprofObject.java │ │ │ ├── HprofPrimitiveType.java │ │ │ ├── HprofProxy.java │ │ │ ├── Instance.java │ │ │ ├── InstanceDump.java │ │ │ ├── JavaClass.java │ │ │ ├── JavaFrameGCRoot.java │ │ │ ├── JavaFrameHprofGCRoot.java │ │ │ ├── JniLocalGCRoot.java │ │ │ ├── JniLocalHprofGCRoot.java │ │ │ ├── LoadClass.java │ │ │ ├── LoadClassSegment.java │ │ │ ├── LongBuffer.java │ │ │ ├── LongHashMap.java │ │ │ ├── LongIterator.java │ │ │ ├── LongMap.java │ │ │ ├── LongSet.java │ │ │ ├── NearestGCRoot.java │ │ │ ├── NumberList.java │ │ │ ├── ObjectArrayDump.java │ │ │ ├── ObjectArrayInstance.java │ │ │ ├── ObjectArrayLazyList.java │ │ │ ├── ObjectArrayValuesLazyList.java │ │ │ ├── ObjectFieldValue.java │ │ │ ├── ObjectSizeSettings.java │ │ │ ├── ObjectType.java │ │ │ ├── PrimitiveArrayDump.java │ │ │ ├── PrimitiveArrayInstance.java │ │ │ ├── PrimitiveArrayLazyList.java │ │ │ ├── PrimitiveType.java │ │ │ ├── StackFrame.java │ │ │ ├── StackFrameSegment.java │ │ │ ├── StackTrace.java │ │ │ ├── StackTraceSegment.java │ │ │ ├── StringSegment.java │ │ │ ├── Summary.java │ │ │ ├── SyntheticClassField.java │ │ │ ├── SyntheticClassObjectValue.java │ │ │ ├── TagBounds.java │ │ │ ├── ThreadObjectGCRoot.java │ │ │ ├── ThreadObjectHprofGCRoot.java │ │ │ ├── TreeObject.java │ │ │ ├── Type.java │ │ │ └── Value.java │ │ └── test/ │ │ └── unit/ │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── jfluid/ │ │ └── heap/ │ │ ├── HeapTest.java │ │ └── testHeapDumpLog.txt │ ├── lib.profiler.ui/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ ├── src/ │ │ │ ├── META-INF/ │ │ │ │ └── services/ │ │ │ │ └── org.graalvm.visualvm.lib.ui.cpu.statistics.StatisticalModuleContainer │ │ │ └── org/ │ │ │ └── graalvm/ │ │ │ └── visualvm/ │ │ │ └── lib/ │ │ │ └── ui/ │ │ │ ├── Bundle.properties │ │ │ ├── Formatters.java │ │ │ ├── LiveResultsPanel.java │ │ │ ├── LiveResultsWindowContributor.java │ │ │ ├── ResultsPanel.java │ │ │ ├── ResultsView.java │ │ │ ├── StringDecorator.java │ │ │ ├── SwingWorker.java │ │ │ ├── UIConstants.java │ │ │ ├── UIUtils.java │ │ │ ├── charts/ │ │ │ │ ├── AbstractBarChartModel.java │ │ │ │ ├── AbstractPieChartModel.java │ │ │ │ ├── BarChart.java │ │ │ │ ├── BarChartModel.java │ │ │ │ ├── Bundle.properties │ │ │ │ ├── ChartActionListener.java │ │ │ │ ├── ChartModelListener.java │ │ │ │ ├── DateTimeAxisUtils.java │ │ │ │ ├── DecimalAxisUtils.java │ │ │ │ ├── DynamicPieChartModel.java │ │ │ │ ├── PieChart.java │ │ │ │ ├── PieChartModel.java │ │ │ │ └── xy/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── ProfilerGCXYItem.java │ │ │ │ ├── ProfilerGCXYItemPainter.java │ │ │ │ ├── ProfilerXYChart.java │ │ │ │ ├── ProfilerXYItemPainter.java │ │ │ │ ├── ProfilerXYSelectionOverlay.java │ │ │ │ ├── ProfilerXYTooltipModel.java │ │ │ │ ├── ProfilerXYTooltipOverlay.java │ │ │ │ └── ProfilerXYTooltipPainter.java │ │ │ ├── components/ │ │ │ │ ├── AnimatedContainer.java │ │ │ │ ├── AnimationLayout.java │ │ │ │ ├── Animator.java │ │ │ │ ├── Bundle.properties │ │ │ │ ├── CellTipAware.java │ │ │ │ ├── CellTipManager.java │ │ │ │ ├── CloseButton.java │ │ │ │ ├── ColorIcon.java │ │ │ │ ├── ComponentMorpher.java │ │ │ │ ├── ComponentMorpher2.java │ │ │ │ ├── CustomTaskButtonBorder.java │ │ │ │ ├── DiscreteProgress.java │ │ │ │ ├── EqualFlowLayout.java │ │ │ │ ├── FilterComponent.java │ │ │ │ ├── FlatToolBar.java │ │ │ │ ├── HTMLLabel.java │ │ │ │ ├── HTMLTextArea.java │ │ │ │ ├── HTMLTextAreaSearchUtils.java │ │ │ │ ├── ImageBlenderPanel.java │ │ │ │ ├── ImagePanel.java │ │ │ │ ├── JAntiLabel.java │ │ │ │ ├── JCheckTree.java │ │ │ │ ├── JCompoundSplitPane.java │ │ │ │ ├── JExtendedComboBox.java │ │ │ │ ├── JExtendedRadioButton.java │ │ │ │ ├── JExtendedSpinner.java │ │ │ │ ├── JExtendedSplitPane.java │ │ │ │ ├── JExtendedTable.java │ │ │ │ ├── JExtendedTree.java │ │ │ │ ├── JTitledPanel.java │ │ │ │ ├── JTreeTable.java │ │ │ │ ├── LazyComboBox.java │ │ │ │ ├── NoCaret.java │ │ │ │ ├── ProfilerToolbar.java │ │ │ │ ├── SnippetPanel.java │ │ │ │ ├── ThinBevelBorder.java │ │ │ │ ├── VerticalLayout.java │ │ │ │ ├── XPStyleBorder.java │ │ │ │ ├── table/ │ │ │ │ │ ├── BooleanTableCellRenderer.java │ │ │ │ │ ├── ClassNameTableCellRenderer.java │ │ │ │ │ ├── CustomBarCellRenderer.java │ │ │ │ │ ├── CustomSortableHeaderRenderer.java │ │ │ │ │ ├── DiffBarCellRenderer.java │ │ │ │ │ ├── EnhancedTableCellRenderer.java │ │ │ │ │ ├── ExtendedTableModel.java │ │ │ │ │ ├── HTMLLabelTableCellRenderer.java │ │ │ │ │ ├── JExtendedTablePanel.java │ │ │ │ │ ├── LabelBracketTableCellRenderer.java │ │ │ │ │ ├── LabelTableCellRenderer.java │ │ │ │ │ ├── MethodNameTableCellRenderer.java │ │ │ │ │ ├── SortableTableModel.java │ │ │ │ │ └── TableCellRendererPersistent.java │ │ │ │ ├── tree/ │ │ │ │ │ ├── CheckTreeCellRenderer.java │ │ │ │ │ ├── CheckTreeNode.java │ │ │ │ │ ├── EnhancedTreeCellRenderer.java │ │ │ │ │ ├── MethodNameTreeCellRenderer.java │ │ │ │ │ └── TreeCellRendererPersistent.java │ │ │ │ └── treetable/ │ │ │ │ ├── AbstractTreeTableModel.java │ │ │ │ ├── ExtendedTreeTableModel.java │ │ │ │ ├── JTreeTablePanel.java │ │ │ │ ├── TreeTableModel.java │ │ │ │ └── TreeTableModelAdapter.java │ │ │ ├── cpu/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── CCTDisplay.java │ │ │ │ ├── CPUJavaNameRenderer.java │ │ │ │ ├── CPUResUserActionsHandler.java │ │ │ │ ├── CPUResultsPanel.java │ │ │ │ ├── CPUSelectionHandler.java │ │ │ │ ├── CPUTableView.java │ │ │ │ ├── CPUTreeTableView.java │ │ │ │ ├── CPUView.java │ │ │ │ ├── CodeRegionLivePanel.java │ │ │ │ ├── CodeRegionSnapshotPanel.java │ │ │ │ ├── CombinedPanel.java │ │ │ │ ├── DiffCCTDisplay.java │ │ │ │ ├── DiffFlatProfilePanel.java │ │ │ │ ├── FlatProfilePanel.java │ │ │ │ ├── LiveCPUView.java │ │ │ │ ├── LiveCPUViewUpdater.java │ │ │ │ ├── LiveFlatProfileCollectorPanel.java │ │ │ │ ├── LiveFlatProfilePanel.java │ │ │ │ ├── ReverseCallGraphPanel.java │ │ │ │ ├── ScreenshotProvider.java │ │ │ │ ├── SnapshotCPUResultsPanel.java │ │ │ │ ├── SnapshotCPUView.java │ │ │ │ ├── SnapshotFlatProfilePanel.java │ │ │ │ ├── StatisticsPanel.java │ │ │ │ ├── SubtreeCallGraphPanel.java │ │ │ │ ├── ThreadsSelector.java │ │ │ │ └── statistics/ │ │ │ │ ├── StatisticalModule.java │ │ │ │ ├── StatisticalModuleContainer.java │ │ │ │ └── TimingData.java │ │ │ ├── graphs/ │ │ │ │ ├── AllocationsHistoryGraphPanel.java │ │ │ │ ├── Bundle.properties │ │ │ │ ├── CPUGraphPanel.java │ │ │ │ ├── ColorFactory.java │ │ │ │ ├── GraphPanel.java │ │ │ │ ├── GraphsUI.java │ │ │ │ ├── LivenessHistoryGraphPanel.java │ │ │ │ ├── MemoryGraphPanel.java │ │ │ │ ├── SurvivingGenerationsGraphPanel.java │ │ │ │ ├── ThreadsGraphPanel.java │ │ │ │ └── XYBackground.java │ │ │ ├── jdbc/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── JDBCJavaNameRenderer.java │ │ │ │ ├── JDBCTreeTableView.java │ │ │ │ ├── JDBCView.java │ │ │ │ ├── LiveJDBCView.java │ │ │ │ ├── LiveJDBCViewUpdater.java │ │ │ │ ├── SQLFilterPanel.java │ │ │ │ ├── SQLFormatter.java │ │ │ │ ├── SnapshotJDBCView.java │ │ │ │ └── TablesSelector.java │ │ │ ├── locks/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── LiveLocksViewUpdater.java │ │ │ │ ├── LockContentionPanel.java │ │ │ │ ├── LockContentionRenderer.java │ │ │ │ └── LockContentionTreeCellRenderer.java │ │ │ ├── memory/ │ │ │ │ ├── ActionsHandler.java │ │ │ │ ├── AllocResultsPanel.java │ │ │ │ ├── AllocTableView.java │ │ │ │ ├── AllocTreeTableView.java │ │ │ │ ├── Bundle.properties │ │ │ │ ├── ClassHistoryActionsHandler.java │ │ │ │ ├── ClassHistoryModels.java │ │ │ │ ├── DiffAllocResultsPanel.java │ │ │ │ ├── DiffLivenessResultsPanel.java │ │ │ │ ├── DiffSampledResultsPanel.java │ │ │ │ ├── LiveAllocResultsPanel.java │ │ │ │ ├── LiveLivenessResultsPanel.java │ │ │ │ ├── LiveMemoryView.java │ │ │ │ ├── LiveMemoryViewUpdater.java │ │ │ │ ├── LiveReverseMemCallGraphPanel.java │ │ │ │ ├── LiveSampledResultsPanel.java │ │ │ │ ├── LivenessResultsPanel.java │ │ │ │ ├── LivenessTableView.java │ │ │ │ ├── LivenessTreeTableView.java │ │ │ │ ├── MemoryCCTTreeModel.java │ │ │ │ ├── MemoryJavaNameRenderer.java │ │ │ │ ├── MemoryResUserActionsHandler.java │ │ │ │ ├── MemoryResultsPanel.java │ │ │ │ ├── MemoryView.java │ │ │ │ ├── ReverseMemCallGraphPanel.java │ │ │ │ ├── SampledResultsPanel.java │ │ │ │ ├── SampledTableView.java │ │ │ │ ├── SnapshotAllocResultsPanel.java │ │ │ │ ├── SnapshotLivenessResultsPanel.java │ │ │ │ ├── SnapshotMemoryView.java │ │ │ │ ├── SnapshotReverseMemCallGraphPanel.java │ │ │ │ └── SnapshotSampledResultsPanel.java │ │ │ ├── monitor/ │ │ │ │ ├── MonitorView.java │ │ │ │ └── VMTelemetryModels.java │ │ │ ├── results/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── ColoredFilter.java │ │ │ │ ├── DataView.java │ │ │ │ └── PackageColorer.java │ │ │ ├── swing/ │ │ │ │ ├── ActionPopupButton.java │ │ │ │ ├── Bundle.properties │ │ │ │ ├── EditableHistoryCombo.java │ │ │ │ ├── ExportUtils.java │ │ │ │ ├── FilterUtils.java │ │ │ │ ├── FilteringToolbar.java │ │ │ │ ├── GenericToolbar.java │ │ │ │ ├── GrayLabel.java │ │ │ │ ├── HeaderComponent.java │ │ │ │ ├── InvisibleToolbar.java │ │ │ │ ├── MultiButtonGroup.java │ │ │ │ ├── PopupButton.java │ │ │ │ ├── ProfilerColumnModel.java │ │ │ │ ├── ProfilerPopup.java │ │ │ │ ├── ProfilerPopupMenu.java │ │ │ │ ├── ProfilerRowSorter.java │ │ │ │ ├── ProfilerTable.java │ │ │ │ ├── ProfilerTableActions.java │ │ │ │ ├── ProfilerTableContainer.java │ │ │ │ ├── ProfilerTableHover.java │ │ │ │ ├── ProfilerTableHovers.java │ │ │ │ ├── ProfilerTreeTable.java │ │ │ │ ├── ProfilerTreeTableModel.java │ │ │ │ ├── SearchUtils.java │ │ │ │ ├── SmallButton.java │ │ │ │ ├── StayOpenPopupMenu.java │ │ │ │ ├── TextArea.java │ │ │ │ └── renderer/ │ │ │ │ ├── BarRenderer.java │ │ │ │ ├── BaseRenderer.java │ │ │ │ ├── CheckBoxRenderer.java │ │ │ │ ├── FormattedLabelRenderer.java │ │ │ │ ├── HideableBarRenderer.java │ │ │ │ ├── JavaNameRenderer.java │ │ │ │ ├── LabelRenderer.java │ │ │ │ ├── McsTimeRenderer.java │ │ │ │ ├── Movable.java │ │ │ │ ├── MultiRenderer.java │ │ │ │ ├── NormalBoldGrayRenderer.java │ │ │ │ ├── NumberPercentRenderer.java │ │ │ │ ├── NumberRenderer.java │ │ │ │ ├── PercentRenderer.java │ │ │ │ ├── ProfilerRenderer.java │ │ │ │ └── RelativeRenderer.java │ │ │ └── threads/ │ │ │ ├── Bundle.properties │ │ │ ├── NameStateRenderer.java │ │ │ ├── ThreadStateIcon.java │ │ │ ├── ThreadTimeRelRenderer.java │ │ │ ├── ThreadsPanel.java │ │ │ ├── TimelineHeaderRenderer.java │ │ │ ├── TimelineRenderer.java │ │ │ └── ViewManager.java │ │ └── test/ │ │ └── unit/ │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── ui/ │ │ └── SwingWorkerTest.java │ ├── profiler/ │ │ ├── build.xml │ │ ├── l10n.list │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ ├── src/ │ │ │ └── org/ │ │ │ └── graalvm/ │ │ │ └── visualvm/ │ │ │ └── lib/ │ │ │ └── profiler/ │ │ │ ├── Bundle.properties │ │ │ ├── DummyHprofResolver.xml │ │ │ ├── HeapDumpWatch.java │ │ │ ├── LoadedSnapshot.java │ │ │ ├── NetBeansProfiler.java │ │ │ ├── NpsResolver.xml │ │ │ ├── ProfilerModule.java │ │ │ ├── ProfilerTopComponent.java │ │ │ ├── ProfilingMonitor.java │ │ │ ├── ResultsListener.java │ │ │ ├── ResultsManager.java │ │ │ ├── SampledCPUSnapshot.java │ │ │ ├── SaveSnapshotAction.java │ │ │ ├── ServerStateMonitor.java │ │ │ ├── SnapshotInfoAction.java │ │ │ ├── SnapshotInfoPanel.java │ │ │ ├── SnapshotResultsWindow.java │ │ │ ├── SnapshotsListener.java │ │ │ ├── ThreadDumpWindow.java │ │ │ ├── actions/ │ │ │ │ ├── AttachAction.java │ │ │ │ ├── Bundle.properties │ │ │ │ ├── CompareSnapshotsAction.java │ │ │ │ ├── GetCmdLineArgumentsAction.java │ │ │ │ ├── HeapDumpAction.java │ │ │ │ ├── InternalStatsAction.java │ │ │ │ ├── JavaPlatformSelector.java │ │ │ │ ├── LoadSnapshotAction.java │ │ │ │ ├── ProfilingAwareAction.java │ │ │ │ ├── ProfilingSupport.java │ │ │ │ ├── ResetResultsAction.java │ │ │ │ ├── RunCalibrationAction.java │ │ │ │ ├── RunGCAction.java │ │ │ │ ├── SnapshotsWindowAction.java │ │ │ │ ├── StopAction.java │ │ │ │ ├── TakeSnapshotAction.java │ │ │ │ └── TakeThreadDumpAction.java │ │ │ ├── impl/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── CloseButtonProvider.java │ │ │ │ ├── ProfilerDialogs.java │ │ │ │ ├── ProfilerDialogsProviderImpl.java │ │ │ │ └── icons/ │ │ │ │ └── IconsProviderImpl.java │ │ │ ├── mf-layer.xml │ │ │ ├── ui/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── HprofDataObject.java │ │ │ │ ├── NBHTMLLabel.java │ │ │ │ ├── NBSwingWorker.java │ │ │ │ ├── NpsDataObject.java │ │ │ │ └── ProfilerProgressDisplayer.java │ │ │ ├── utils/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── MainClassChooser.java │ │ │ │ └── MainClassWarning.java │ │ │ └── v2/ │ │ │ ├── ProfilerFeature.java │ │ │ ├── ProfilerFeatures.java │ │ │ ├── ProfilerPlugin.java │ │ │ ├── ProfilerPlugins.java │ │ │ ├── ProfilerSession.java │ │ │ ├── ProfilerSessions.java │ │ │ ├── ProfilerWindow.java │ │ │ ├── SessionStorage.java │ │ │ ├── SnapshotsWindow.java │ │ │ ├── features/ │ │ │ │ ├── FeatureMode.java │ │ │ │ ├── FeatureUI.java │ │ │ │ ├── LocksFeature.java │ │ │ │ ├── LocksFeatureUI.java │ │ │ │ ├── MethodsFeature.java │ │ │ │ ├── MethodsFeatureModes.java │ │ │ │ ├── MethodsFeatureUI.java │ │ │ │ ├── MonitorFeature.java │ │ │ │ ├── MonitorFeatureUI.java │ │ │ │ ├── ObjectsFeature.java │ │ │ │ ├── ObjectsFeatureModes.java │ │ │ │ ├── ObjectsFeatureUI.java │ │ │ │ ├── SQLFeature.java │ │ │ │ ├── SQLFeatureModes.java │ │ │ │ ├── SQLFeatureUI.java │ │ │ │ ├── ThreadsFeature.java │ │ │ │ └── ThreadsFeatureUI.java │ │ │ ├── impl/ │ │ │ │ ├── ClassMethodList.java │ │ │ │ ├── ClassMethodSelector.java │ │ │ │ ├── FeaturesView.java │ │ │ │ ├── FilterSelector.java │ │ │ │ ├── ProfilerStatus.java │ │ │ │ ├── ProjectsSelector.java │ │ │ │ ├── SnapshotsWindowHelper.java │ │ │ │ ├── SnapshotsWindowUI.java │ │ │ │ ├── WeakProcessor.java │ │ │ │ └── WelcomePanel.java │ │ │ └── ui/ │ │ │ ├── DropdownButton.java │ │ │ ├── ProjectSelector.java │ │ │ ├── SettingsPanel.java │ │ │ ├── TitledMenuSeparator.java │ │ │ └── ToggleButtonMenuItem.java │ │ └── test/ │ │ ├── qa-functional/ │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── netbeans/ │ │ │ └── test/ │ │ │ └── profiler/ │ │ │ └── ProfilerValidationTest.java │ │ └── unit/ │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── profiler/ │ │ └── actions/ │ │ └── SelfSamplerActionTest.java │ ├── profiler.api/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── profiler/ │ │ ├── api/ │ │ │ ├── ActionsSupport.java │ │ │ ├── Bundle.properties │ │ │ ├── EditorContext.java │ │ │ ├── EditorSupport.java │ │ │ ├── GestureSubmitter.java │ │ │ ├── GoToSource.java │ │ │ ├── JavaPlatform.java │ │ │ ├── ProfilerDialogs.java │ │ │ ├── ProfilerIDESettings.java │ │ │ ├── ProfilerProject.java │ │ │ ├── ProfilerSource.java │ │ │ ├── ProfilerStorage.java │ │ │ ├── ProgressDisplayer.java │ │ │ ├── ProjectUtilities.java │ │ │ ├── icons/ │ │ │ │ ├── GeneralIcons.java │ │ │ │ ├── Icons.java │ │ │ │ ├── LanguageIcons.java │ │ │ │ └── ProfilerIcons.java │ │ │ ├── java/ │ │ │ │ ├── ExternalPackages.java │ │ │ │ ├── JavaProfilerSource.java │ │ │ │ ├── ProfilerTypeUtils.java │ │ │ │ ├── SourceClassInfo.java │ │ │ │ ├── SourceMethodInfo.java │ │ │ │ └── SourcePackageInfo.java │ │ │ └── project/ │ │ │ ├── ProjectContentsSupport.java │ │ │ └── ProjectProfilingSupport.java │ │ └── spi/ │ │ ├── ActionsSupportProvider.java │ │ ├── EditorSupportProvider.java │ │ ├── IconsProvider.java │ │ ├── JavaPlatformManagerProvider.java │ │ ├── JavaPlatformProvider.java │ │ ├── LoadGenPlugin.java │ │ ├── ProfilerDialogsProvider.java │ │ ├── ProfilerStorageProvider.java │ │ ├── ProjectUtilitiesProvider.java │ │ ├── SessionListener.java │ │ ├── java/ │ │ │ ├── AbstractJavaProfilerSource.java │ │ │ ├── GoToSourceProvider.java │ │ │ └── ProfilerTypeUtilsProvider.java │ │ └── project/ │ │ ├── Bundle.properties │ │ ├── ProjectContentsSupportProvider.java │ │ └── ProjectProfilingSupportProvider.java │ ├── profiler.attach/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── profiler/ │ │ └── attach/ │ │ ├── AttachWizard.java │ │ ├── Bundle.properties │ │ ├── dialog/ │ │ │ └── AttachDialog.java │ │ ├── providers/ │ │ │ ├── RemotePackExporter.java │ │ │ └── TargetPlatformEnum.java │ │ ├── spi/ │ │ │ ├── AbstractRemotePackExporter.java │ │ │ └── AttachStepsProvider.java │ │ └── steps/ │ │ └── BasicAttachStepsProvider.java │ ├── profiler.heapwalker/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── profiler/ │ │ ├── heapwalk/ │ │ │ ├── details/ │ │ │ │ ├── api/ │ │ │ │ │ ├── DetailsSupport.java │ │ │ │ │ ├── ExportAction.java │ │ │ │ │ └── StringDecoder.java │ │ │ │ ├── basic/ │ │ │ │ │ ├── ArrayDetailsProvider.java │ │ │ │ │ ├── ArrayValueView.java │ │ │ │ │ ├── PrimitiveDetailsProvider.java │ │ │ │ │ └── StringDetailsProvider.java │ │ │ │ ├── jdk/ │ │ │ │ │ ├── AtomicDetailsProvider.java │ │ │ │ │ ├── IoDetailsProvider.java │ │ │ │ │ ├── JmxDetailsProvider.java │ │ │ │ │ ├── LangDetailsProvider.java │ │ │ │ │ ├── MathDetailsProvider.java │ │ │ │ │ ├── ModuleDetailsProvider.java │ │ │ │ │ ├── NetDetailsProvider.java │ │ │ │ │ ├── NioDetailsProvider.java │ │ │ │ │ ├── ReferenceDetailsProvider.java │ │ │ │ │ ├── ReflectionDetailsProvider.java │ │ │ │ │ ├── SecurityDetailsProvider.java │ │ │ │ │ ├── ThreadDetailsProvider.java │ │ │ │ │ ├── TimeDetailsProvider.java │ │ │ │ │ ├── UtilDetailsProvider.java │ │ │ │ │ ├── image/ │ │ │ │ │ │ ├── FieldAccessor.java │ │ │ │ │ │ ├── ImageBuilder.java │ │ │ │ │ │ ├── ImageDetailProvider.java │ │ │ │ │ │ ├── ImageExportAction.java │ │ │ │ │ │ ├── InstanceBuilder.java │ │ │ │ │ │ └── InstanceBuilderRegistry.java │ │ │ │ │ └── ui/ │ │ │ │ │ ├── AwtDetailsProvider.java │ │ │ │ │ ├── BaseBuilders.java │ │ │ │ │ ├── BorderBuilders.java │ │ │ │ │ ├── ButtonBuilders.java │ │ │ │ │ ├── ComponentBuilders.java │ │ │ │ │ ├── ComponentDetailsProvider.java │ │ │ │ │ ├── DataViewBuilders.java │ │ │ │ │ ├── JComponentBuilders.java │ │ │ │ │ ├── PaneBuilders.java │ │ │ │ │ ├── TextComponentBuilders.java │ │ │ │ │ ├── Utils.java │ │ │ │ │ └── WindowBuilders.java │ │ │ │ ├── netbeans/ │ │ │ │ │ ├── EditorDetailsProvider.java │ │ │ │ │ ├── JavaDetailsProvider.java │ │ │ │ │ ├── JavacDetailsProvider.java │ │ │ │ │ ├── PlatformDetailsProvider.java │ │ │ │ │ └── VCSDetailsProvider.java │ │ │ │ └── spi/ │ │ │ │ ├── DetailsProvider.java │ │ │ │ └── DetailsUtils.java │ │ │ ├── memorylint/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── Distribution.java │ │ │ │ ├── FieldAccess.java │ │ │ │ ├── Histogram.java │ │ │ │ ├── IteratingRule.java │ │ │ │ ├── MemoryLint.java │ │ │ │ ├── Rule.java │ │ │ │ ├── RuleRegistry.java │ │ │ │ ├── StringHelper.java │ │ │ │ ├── Utils.java │ │ │ │ ├── Walker.java │ │ │ │ └── rules/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── CollapsedHashMap.java │ │ │ │ ├── DeepSize.java │ │ │ │ ├── DuplicatedString.java │ │ │ │ ├── HashMapHistogram.java │ │ │ │ ├── OverallocatedString.java │ │ │ │ ├── RetainedSetByClass.java │ │ │ │ ├── RetainedSetByInstance.java │ │ │ │ ├── TooManyBooleans.java │ │ │ │ └── WrongWeakHashMap.java │ │ │ ├── model/ │ │ │ │ └── BrowserUtils.java │ │ │ └── ui/ │ │ │ └── icons/ │ │ │ ├── HeapWalkerIcons.java │ │ │ └── impl/ │ │ │ └── HeapWalkerIconsProviderImpl.java │ │ └── heapwalker/ │ │ └── Bundle.properties │ ├── profiler.oql/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ ├── src/ │ │ │ └── org/ │ │ │ └── graalvm/ │ │ │ └── visualvm/ │ │ │ └── lib/ │ │ │ └── profiler/ │ │ │ └── oql/ │ │ │ ├── Bundle.properties │ │ │ ├── engine/ │ │ │ │ └── api/ │ │ │ │ ├── OQLEngine.java │ │ │ │ ├── OQLException.java │ │ │ │ ├── ReferenceChain.java │ │ │ │ └── impl/ │ │ │ │ ├── Bundle.properties │ │ │ │ ├── OQLEngineImpl.java │ │ │ │ ├── OQLQueryImpl.java │ │ │ │ ├── ReachableExcludes.java │ │ │ │ ├── ReachableObjects.java │ │ │ │ ├── Snapshot.java │ │ │ │ ├── TreeIterator.java │ │ │ │ └── hat.js │ │ │ ├── icons/ │ │ │ │ ├── OQLIcons.java │ │ │ │ └── impl/ │ │ │ │ └── OQLIconsProviderImpl.java │ │ │ ├── layer.xml │ │ │ ├── repository/ │ │ │ │ ├── api/ │ │ │ │ │ ├── OQLQueryCategory.java │ │ │ │ │ ├── OQLQueryDefinition.java │ │ │ │ │ └── OQLQueryRepository.java │ │ │ │ ├── permgen/ │ │ │ │ │ └── resources/ │ │ │ │ │ ├── BootstrapCount.oql │ │ │ │ │ ├── Bundle.properties │ │ │ │ │ ├── CLChildParent.oql │ │ │ │ │ ├── CLHisto.oql │ │ │ │ │ ├── CLLiveness.oql │ │ │ │ │ ├── CLLoadedClasses.oql │ │ │ │ │ ├── CLReflection.oql │ │ │ │ │ └── CLTypes.oql │ │ │ │ └── resources/ │ │ │ │ ├── AllFiles.oql │ │ │ │ ├── Bundle.properties │ │ │ │ ├── OverallocatedStrings.oql │ │ │ │ ├── OverallocatedStringsJS.oql │ │ │ │ └── TooManyBooleans.oql │ │ │ └── spi/ │ │ │ └── OQLEditorImpl.java │ │ └── test/ │ │ └── unit/ │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── profiler/ │ │ └── oql/ │ │ ├── engine/ │ │ │ └── api/ │ │ │ └── impl/ │ │ │ └── OQLEngineTest.java │ │ └── repository/ │ │ └── api/ │ │ └── OQLQueryRepositoryTest.java │ ├── profiler.snaptracer/ │ │ ├── build.xml │ │ ├── manifest.mf │ │ ├── nbproject/ │ │ │ ├── build-impl.xml │ │ │ ├── genfiles.properties │ │ │ ├── project.properties │ │ │ ├── project.xml │ │ │ └── suite.properties │ │ └── src/ │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── lib/ │ │ └── profiler/ │ │ └── snaptracer/ │ │ ├── Bundle.properties │ │ ├── ClassNameComparator.java │ │ ├── ItemValueFormatter.java │ │ ├── PackageStateHandler.java │ │ ├── Positionable.java │ │ ├── ProbeItemDescriptor.java │ │ ├── ProbeStateHandler.java │ │ ├── SessionInitializationException.java │ │ ├── TracerPackage.java │ │ ├── TracerPackageProvider.java │ │ ├── TracerProbe.java │ │ ├── TracerProbeDescriptor.java │ │ ├── TracerProgressObject.java │ │ ├── TracerSupport.java │ │ ├── impl/ │ │ │ ├── Bundle.properties │ │ │ ├── DetailsView.java │ │ │ ├── ExportSnapshotAction.java │ │ │ ├── IdeSnapshot.java │ │ │ ├── IdeSnapshotAction.java │ │ │ ├── NpssDataObject.java │ │ │ ├── TimelineView.java │ │ │ ├── TracerController.java │ │ │ ├── TracerModel.java │ │ │ ├── TracerSupportImpl.java │ │ │ ├── TracerView.java │ │ │ ├── details/ │ │ │ │ ├── DetailsPanel.java │ │ │ │ ├── DetailsTable.java │ │ │ │ ├── DetailsTableCellRenderer.java │ │ │ │ ├── DetailsTableModel.java │ │ │ │ ├── ItemValueRenderer.java │ │ │ │ ├── MarkRenderer.java │ │ │ │ └── TimestampRenderer.java │ │ │ ├── export/ │ │ │ │ ├── CSVExporter.java │ │ │ │ ├── DataExport.java │ │ │ │ ├── ExportBatch.java │ │ │ │ ├── Exporter.java │ │ │ │ ├── HTMLExporter.java │ │ │ │ └── XMLExporter.java │ │ │ ├── icons/ │ │ │ │ ├── TracerIcons.java │ │ │ │ └── TracerIconsProviderImpl.java │ │ │ ├── options/ │ │ │ │ ├── TracerOptions.java │ │ │ │ ├── TracerOptionsCategory.java │ │ │ │ ├── TracerOptionsPanel.java │ │ │ │ └── TracerOptionsPanelController.java │ │ │ ├── packages/ │ │ │ │ ├── TestPackage.java │ │ │ │ ├── TestPackageProvider.java │ │ │ │ ├── TestProbe.java │ │ │ │ └── UiGesturesProbe.java │ │ │ ├── probes/ │ │ │ │ ├── ProbeDescriptorComponent.java │ │ │ │ └── ProbePresenter.java │ │ │ ├── resources/ │ │ │ │ └── NpssResolver.xml │ │ │ ├── swing/ │ │ │ │ ├── ColorIcon.java │ │ │ │ ├── CustomComboRenderer.java │ │ │ │ ├── DropdownButton.java │ │ │ │ ├── EnhancedLabelRenderer.java │ │ │ │ ├── HeaderButton.java │ │ │ │ ├── HeaderLabel.java │ │ │ │ ├── HeaderPanel.java │ │ │ │ ├── HorizontalLayout.java │ │ │ │ ├── LabelRenderer.java │ │ │ │ ├── LegendFont.java │ │ │ │ ├── ScrollBar.java │ │ │ │ ├── ScrollableContainer.java │ │ │ │ ├── SectionSeparator.java │ │ │ │ ├── Separator.java │ │ │ │ ├── SimpleSeparator.java │ │ │ │ ├── Spacer.java │ │ │ │ ├── TimelineMarksPainter.java │ │ │ │ ├── TransparentToolBar.java │ │ │ │ ├── VerticalLayout.java │ │ │ │ └── VisibilityHandler.java │ │ │ └── timeline/ │ │ │ ├── Bundle.properties │ │ │ ├── ChartPanel.java │ │ │ ├── ContinuousXYPainter.java │ │ │ ├── DiscreteXYPainter.java │ │ │ ├── PointsComputer.java │ │ │ ├── ProbesPanel.java │ │ │ ├── RowBackgroundDecorator.java │ │ │ ├── RowBoundsDecorator.java │ │ │ ├── RowForegroundDecorator.java │ │ │ ├── TimelineAxis.java │ │ │ ├── TimelineChart.java │ │ │ ├── TimelineColorFactory.java │ │ │ ├── TimelineIconPainter.java │ │ │ ├── TimelineLegendOverlay.java │ │ │ ├── TimelineModel.java │ │ │ ├── TimelinePaintersFactory.java │ │ │ ├── TimelinePanel.java │ │ │ ├── TimelineSelectionManager.java │ │ │ ├── TimelineSelectionOverlay.java │ │ │ ├── TimelineSupport.java │ │ │ ├── TimelineTooltipOverlay.java │ │ │ ├── TimelineTooltipPainter.java │ │ │ ├── TimelineUnitsOverlay.java │ │ │ ├── TimelineXYItem.java │ │ │ ├── TimelineXYPainter.java │ │ │ ├── VerticalTimelineLayout.java │ │ │ ├── XChartSelectionOverlay.java │ │ │ └── items/ │ │ │ ├── ContinuousXYItemDescriptor.java │ │ │ ├── DiscreteXYItemDescriptor.java │ │ │ ├── IconItemDescriptor.java │ │ │ ├── ValueItemDescriptor.java │ │ │ └── XYItemDescriptor.java │ │ ├── logs/ │ │ │ ├── LogReader.java │ │ │ └── LogRecords.java │ │ └── package-info.java │ └── profiler.utilities/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── lib/ │ └── profiler/ │ └── utilities/ │ ├── Bundle.properties │ ├── Delegate.java │ ├── OutputParameter.java │ ├── ProfilerUtils.java │ ├── Visitable.java │ └── Visitor.java ├── maven-repo.sh ├── nashorn.jdk15/ │ ├── build.xml │ ├── external/ │ │ ├── asm-util-9.7-license.txt │ │ ├── binaries-list │ │ └── nashorn-core-15.6-license.txt │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ ├── graalvm/ │ │ └── visualvm/ │ │ └── nashorn/ │ │ └── jdk15/ │ │ └── Bundle.properties │ └── openjdk/ │ └── nashorn/ │ └── internal/ │ └── runtime/ │ └── linker/ │ └── JavaAdapterFactory.java ├── nbproject/ │ ├── build-impl.xml │ ├── genfiles.properties │ ├── platform.properties │ ├── platform.xml │ ├── project.properties │ ├── project.xml │ └── suite.properties ├── pluginimporter/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── pluginimporter/ │ ├── Bundle.properties │ ├── ClusterUpdateProvider.java │ ├── ImportManager.form │ ├── ImportManager.java │ ├── Installer.java │ └── PluginImporter.java ├── profiler/ │ ├── build.xml │ ├── libsrc/ │ │ ├── manifest.mf │ │ └── org/ │ │ └── graalvm/ │ │ └── visualvm/ │ │ └── profiler/ │ │ └── JavaSysProperties.java │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── profiler/ │ ├── ApplicationProfilerView.java │ ├── ApplicationProfilerViewProvider.java │ ├── Bundle.properties │ ├── CPULivePanel.java │ ├── CPUSettingsSupport.java │ ├── CalibrationSupport.java │ ├── DummyProjectProvider.java │ ├── JDBCLivePanel.java │ ├── JDBCSettingsSupport.java │ ├── JavaInfo.java │ ├── JavaPlatformCache.java │ ├── JavaPlatformSelector.java │ ├── LocksLivePanel.java │ ├── LocksSettingsSupport.java │ ├── ManageCalibration.java │ ├── MemoryLivePanel.java │ ├── MemorySettingsSupport.java │ ├── ProfileApplicationAction.java │ ├── ProfilerSettingsSupport.java │ ├── ProfilerSnapshotAction.java │ ├── ProfilerSupport.java │ ├── ProfilingResultsSupport.java │ ├── VisualVMProfiler.java │ └── resources/ │ └── layer.xml ├── profiling/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── platform.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── profiling/ │ ├── Bundle.properties │ ├── Installer.java │ ├── actions/ │ │ ├── ProfiledSourceSelection.java │ │ ├── ProfilerActionsSupport.java │ │ ├── ProfilerPopupCustomizer.java │ │ └── ProfilerResultsAction.java │ ├── presets/ │ │ ├── Bundle.properties │ │ ├── PresetSelector.java │ │ ├── PresetsUtils.java │ │ ├── ProfilerCPUPanel.java │ │ ├── ProfilerCPUSettings.java │ │ ├── ProfilerJDBCPanel.java │ │ ├── ProfilerJDBCSettings.java │ │ ├── ProfilerLocksPanel.java │ │ ├── ProfilerMemoryPanel.java │ │ ├── ProfilerMemorySettings.java │ │ ├── ProfilerPreset.java │ │ ├── ProfilerPresets.java │ │ ├── ProfilingOptionsPanel.java │ │ ├── ProfilingOptionsPanelController.java │ │ ├── ProfilingOptionsSectionProvider.java │ │ ├── SamplerCPUPanel.java │ │ ├── SamplerCPUSettings.java │ │ ├── SamplerMemoryPanel.java │ │ └── SamplerMemorySettings.java │ └── snapshot/ │ ├── Bundle.properties │ ├── ProfilerSnapshot.java │ ├── ProfilerSnapshotCategory.java │ ├── ProfilerSnapshotDescriptor.java │ ├── ProfilerSnapshotDescriptorProvider.java │ ├── ProfilerSnapshotNPS.java │ ├── ProfilerSnapshotNPSS.java │ ├── ProfilerSnapshotProvider.java │ ├── ProfilerSnapshotView.java │ ├── ProfilerSnapshotViewProvider.java │ └── ProfilerSnapshotsSupport.java ├── sa/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── sa/ │ ├── Agent.java │ ├── Arguments.java │ ├── Bundle.properties │ ├── Installer.java │ ├── SAObject.java │ ├── SAWrapper.java │ ├── SaModelImpl.java │ ├── SaModelProvider.java │ ├── StackTrace.java │ └── VM.java ├── sampler/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── sampler/ │ ├── AbstractSamplerSupport.java │ ├── ApplicationSamplerView.java │ ├── ApplicationSamplerViewProvider.java │ ├── Bundle.properties │ ├── Installer.java │ ├── SampleApplicationAction.java │ ├── SamplerArguments.java │ ├── SamplerImpl.java │ ├── SamplerInitialization.java │ ├── SamplerParameters.java │ ├── SamplerSupport.java │ ├── cpu/ │ │ ├── Bundle.properties │ │ ├── CCTFlattener.java │ │ ├── CPUSamplerParameters.java │ │ ├── CPUSamplerSupport.java │ │ ├── CPUSettingsSupport.java │ │ ├── CPUView.java │ │ ├── FlatProfileBuilder.java │ │ ├── FlatProfilerContainer.java │ │ ├── SampledLivePanel.java │ │ ├── ThreadInfoProvider.java │ │ ├── ThreadsCPU.java │ │ ├── ThreadsCPUInfo.java │ │ └── ThreadsCPUView.java │ ├── memory/ │ │ ├── Bundle.properties │ │ ├── MemorySamplerParameters.java │ │ ├── MemorySamplerSupport.java │ │ ├── MemorySettingsSupport.java │ │ ├── MemoryView.java │ │ ├── ThreadsMemory.java │ │ ├── ThreadsMemoryInfo.java │ │ └── ThreadsMemoryView.java │ └── resources/ │ └── layer.xml ├── sampler.truffle/ │ ├── build.xml │ ├── libsrc/ │ │ ├── com/ │ │ │ └── oracle/ │ │ │ └── truffle/ │ │ │ ├── api/ │ │ │ │ └── nodes/ │ │ │ │ └── LanguageInfo.java │ │ │ └── tools/ │ │ │ └── profiler/ │ │ │ ├── CPUSampler.java │ │ │ ├── HeapMonitor.java │ │ │ ├── HeapSummary.java │ │ │ └── StackTraceEntry.java │ │ ├── manifest.mf │ │ └── org/ │ │ └── graalvm/ │ │ ├── polyglot/ │ │ │ └── Engine.java │ │ └── visualvm/ │ │ └── sampler/ │ │ └── truffle/ │ │ └── stagent/ │ │ ├── AgentClassLoader.java │ │ ├── Truffle.java │ │ ├── TruffleClassLoader.java │ │ ├── TruffleJMX.java │ │ └── TruffleMBean.java │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── sampler/ │ └── truffle/ │ ├── AbstractSamplerSupport.java │ ├── ApplicationSamplerView.java │ ├── ApplicationSamplerViewProvider.java │ ├── Bundle.properties │ ├── Installer.java │ ├── ProxyTruffleMBean.java │ ├── SampleApplicationAction.java │ ├── SamplerImpl.java │ ├── SamplerSupport.java │ ├── TruffleDataProvider.java │ ├── cpu/ │ │ ├── Bundle.properties │ │ ├── CCTFlattener.java │ │ ├── CPUSamplerSupport.java │ │ ├── CPUSettingsSupport.java │ │ ├── CPUView.java │ │ ├── FlatProfileBuilder.java │ │ ├── FlatProfilerContainer.java │ │ ├── SampledLivePanel.java │ │ └── ThreadInfoProvider.java │ ├── memory/ │ │ ├── Bundle.properties │ │ ├── MemoryHistogramProvider.java │ │ ├── MemorySamplerSupport.java │ │ ├── MemorySettingsSupport.java │ │ └── MemoryView.java │ └── resources/ │ └── layer.xml ├── startup/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── modules/ │ └── startup/ │ ├── AcceptLicense.java │ ├── Bundle.properties │ ├── CopyFiles.java │ ├── ImportPanel.java │ ├── ImportSettings.java │ ├── LICENSE.txt │ ├── LicensePanel.form │ ├── LicensePanel.java │ ├── Utils.java │ ├── VisualVMStartup.java │ └── dialogs/ │ └── StartupDialog.java ├── threaddump/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── threaddump/ │ ├── Bundle.properties │ ├── Installer.java │ ├── ThreadDump.java │ ├── ThreadDumpDescriptor.java │ ├── ThreadDumpSupport.java │ ├── impl/ │ │ ├── Bundle.properties │ │ ├── ThreadDumpAction.java │ │ ├── ThreadDumpArgument.java │ │ ├── ThreadDumpCategory.java │ │ ├── ThreadDumpDescriptorProvider.java │ │ ├── ThreadDumpImpl.java │ │ ├── ThreadDumpProvider.java │ │ ├── ThreadDumpView.java │ │ └── ThreadDumpViewProvider.java │ ├── package-info.java │ └── resources/ │ └── layer.xml ├── tools/ │ ├── build.xml │ ├── manifest.mf │ ├── nbproject/ │ │ ├── build-impl.xml │ │ ├── genfiles.properties │ │ ├── project.properties │ │ ├── project.xml │ │ └── suite.properties │ └── src/ │ └── org/ │ └── graalvm/ │ └── visualvm/ │ └── tools/ │ ├── Bundle.properties │ ├── attach/ │ │ ├── AttachModel.java │ │ ├── AttachModelFactory.java │ │ └── package-info.java │ ├── jfr/ │ │ ├── JfrModel.java │ │ └── JfrModelFactory.java │ ├── jmx/ │ │ ├── CachedMBeanServerConnection.java │ │ ├── CachedMBeanServerConnectionFactory.java │ │ ├── JmxModel.java │ │ ├── JmxModelFactory.java │ │ ├── JvmMXBeans.java │ │ ├── JvmMXBeansFactory.java │ │ ├── MBeanCacheListener.java │ │ ├── MBeanCacheOperations.java │ │ └── package-info.java │ ├── jvmstat/ │ │ ├── Bundle.properties │ │ ├── JvmJvmstatModel.java │ │ ├── JvmJvmstatModelFactory.java │ │ ├── JvmstatListener.java │ │ ├── JvmstatModel.java │ │ ├── JvmstatModelFactory.java │ │ ├── MonitoredValue.java │ │ └── package-info.java │ └── sa/ │ ├── SaModel.java │ ├── SaModelFactory.java │ └── package-info.java └── uisupport/ ├── build.xml ├── manifest.mf ├── nbproject/ │ ├── build-impl.xml │ ├── project.properties │ ├── project.xml │ └── suite.properties └── src/ └── org/ └── graalvm/ └── visualvm/ └── uisupport/ ├── Bundle.properties ├── HTMLLabel.java ├── HTMLTextArea.java ├── HorizontalLayout.java ├── JExtendedSpinner.java ├── ProfilerTabbedPane.java ├── ProfilerTabbedView.java ├── SeparatorLine.java ├── TransparentToolBar.java ├── UISupport.java └── VerticalLayout.java ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve VisualVM title: '' labels: bug assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **VisualVM log** Please attach VisualVM messages.log file to help diagnose your problem. messages.log is available via Help | About | Logfile and via VisualVM | About VisualVM | Logfile on macOS **Screenshots** If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. MacOS] - JDK version [JDK 1.8.0_181] - Version [e.g. 2.0] **Additional context** Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for VisualVM title: '' labels: enhancement assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .gitignore ================================================ /visualvm/nbproject/private/ /visualvm/*/nbproject/private/ /visualvm/libs.profiler/*/nbproject/private/ /visualvm/launcher/windows-src/nbproject/private/ /visualvm/*/build/ /visualvm/*/external/*.jar /visualvm/libs.profiler/*/build/ /plugins/*/build/ /plugins/*/nbproject/private/ /plugins/*/external/*.jar /plugins/visualvm/ /plugins/glassfish/amx-api/build/ /samples/*/build/ /samples/*/nbproject/private/ /*/build/ /*/dist/ /visualvm/netbeans/ /visualvm/nbantext.jar /l10n/en.nbms/ /l10n/l10nantext.jar /plugins/nbproject/private/ # Ignore Mac DS_Store files .DS_Store ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to VisualVM ## Opening issues Please let us know your ideas, missing features, or bugs found. Either [file a RFE/bug](https://github.com/oracle/visualvm/issues/new/choose) or [leave us a message](https://visualvm.github.io/feedback.html). Any information, ideas or suggestions that you provide to us either through a Bug Report or a Feature Request ([https://github.com/oracle/visualvm/issues/new/choose](https://github.com/oracle/visualvm/issues/new/choose)) or using Gitter chat or email shall be considered Feedback. If you think you've found a security vulnerability, do not raise a GitHub issue and follow the instructions in our [security policy](./SECURITY.md). ## Contributing code For legal reasons, we cannot accept external pull requests. ## Pull request process **Pull requests are currently not being accepted for the VisualVM project.** ## Code of conduct Oracle and its affiliates have a perpetual, royalty-free, non-exclusive, irrevocable license to use, reproduce, distribute or otherwise commercialize any Feedback that you voluntarily provide. Oracle shall have no obligation to respond to any Feedback or to incorporate your Feedback into the VisualVM software. [OCA]: https://oca.opensource.oracle.com ================================================ FILE: LICENSE.txt ================================================ Project VisualVM The GNU General Public License (GPL) Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. One line to give the program's name and a brief idea of what it does. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free software, and you are welcome to redistribute it under certain conditions; type 'show c' for details. The hypothetical commands 'show w' and 'show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than 'show w' and 'show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program 'Gnomovision' (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. "CLASSPATH" EXCEPTION TO THE GPL Certain source files distributed by Oracle America and/or its affiliates are subject to the following clarification and special exception to the GPL, but only where Oracle has expressly included in the particular source file's header the words "Oracle designates this particular file as subject to the "Classpath" exception as provided by Oracle in the LICENSE file that accompanied this code." Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination. As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. ================================================ FILE: README.md ================================================ # VisualVM (master) sources repository VisualVM is a visual tool integrating commandline JDK tools and lightweight profiling capabilities. See https://visualvm.github.io for details, downloads and documentation. ## Get the tools Use Apache Ant 1.9.15 or above and Oracle JDK 8 to build VisualVM from this repository. ## Get the sources First download or clone this repository into directory `visualvm`. There are two project suites included: * visualvm (`visualvm/visualvm`) - suite for the core VisualVM tool * plugins (`visualvm/plugins`) - suite for the VisualVM plugins available in Plugins Center ## Configure the dependencies Then download and extract the [NetBeans Platform 22](https://github.com/oracle/visualvm/releases/download/2.2.1/nb220_platform_20260201.zip) into directory `visualvm/visualvm` (should create `visualvm/visualvm/netbeans`). ## How to build To build VisualVM, use `ant build-zip` command in the `visualvm/visualvm` directory. ## How to run To run VisualVM, use `ant run` command in the `visualvm/visualvm` directory. ## Build and run plugins To build or run the plugins suite, use `ant build` or `ant run` in the `visualvm/plugins` directory. This will automatically build the zip distribution of the core VisualVM tool into `visualvm/visualvm/dist/visualvm.zip` and extract it into the `visualvm/plugins/visualvm` directory. After that the build of the plugins suite continues to build each of the individual plugins. Running the plugins suite means starting VisualVM with all the plugins installed. ## Contributing We highly appreciate any feedback! Please let us know your ideas, missing features, or bugs found. Either [file a RFE/bug](https://github.com/oracle/visualvm/issues/new/choose) or [leave us a message](https://visualvm.github.io/feedback.html). For legal reasons, we cannot accept external pull requests. See [CONTRIBUTING](./CONTRIBUTING.md) for details. ## Security Please consult the [security guide](./SECURITY.md) for our responsible security vulnerability disclosure process ## License Copyright (c) 2017, 2025 Oracle and/or its affiliates. Released under the GNU General Public License, version 2, with the Classpath Exception. ================================================ FILE: SECURITY.md ================================================ # Reporting security vulnerabilities Oracle values the independent security research community and believes that responsible disclosure of security vulnerabilities helps us ensure the security and privacy of all our users. Please do NOT raise a GitHub Issue to report a security vulnerability. If you believe you have found a security vulnerability, please submit a report to [secalert_us@oracle.com][1] preferably with a proof of concept. Please review some additional information on [how to report security vulnerabilities to Oracle][2]. We encourage people who contact Oracle Security to use email encryption using [our encryption key][3]. We ask that you do not use other channels or contact the project maintainers directly. Non-vulnerability related security issues including ideas for new or improved security features are welcome on GitHub Issues. ## Security updates, alerts and bulletins Security updates will be released on a regular cadence. Many of our projects will typically release security fixes in conjunction with the Oracle Critical Patch Update program. Additional information, including past advisories, is available on our [security alerts][4] page. ## Security-related information We will provide security related information such as a threat model, considerations for secure use, or any known security issues in our documentation. Please note that labs and sample code are intended to demonstrate a concept and may not be sufficiently hardened for production use. [1]: mailto:secalert_us@oracle.com [2]: https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html [3]: https://www.oracle.com/security-alerts/encryptionkey.html [4]: https://www.oracle.com/security-alerts/ ================================================ FILE: THIRDPARTYLICENSE ================================================ Apache NetBeans License and Third party licenses information Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ******* List of Third Party Components *********** Apache NetBeans includes a number of components and libraries with separate copyright notices and license terms. Your use of those components are subject to the terms and conditions of the following licenses. THIRD-PARTY COMPONENT FILE VERSION LICENSE platform/modules/ext/flatlaf-3.3.jar 3.3 Apache-2.0 platform/modules/lib/flatlaf-windows-arm64.dll 3.3 Apache-2.0 platform/modules/lib/flatlaf-windows-x86.dll 3.3 Apache-2.0 platform/modules/lib/flatlaf-windows-x86_64.dll 3.3 Apache-2.0 platform/modules/lib/libflatlaf-linux-x86_64.so 3.3 Apache-2.0 platform/modules/lib/libflatlaf-macos-arm64.dylib 3.3 Apache-2.0 platform/modules/lib/libflatlaf-macos-x86_64.dylib 3.3 Apache-2.0 platform/modules/ext/jna-5.14.jar 5.14 Apache-2.0 platform/modules/ext/jna-platform-5.14.jar 5.14 Apache-2.0 platform/core/asm-tree-9.7.jar 9.7 BSD-INRIA platform/core/asm-9.7.jar 9.7 BSD-INRIA platform/core/asm-commons-9.7.jar 9.7 BSD-INRIA ******************************************************************************* BSD-INRIA ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, France Telecom All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher/.project ================================================ VisualVM Launcher org.eclipse.visualvm.launcher.common org.eclipse.visualvm.launcher.java org.eclipse.visualvm.launcher.pde org.eclipse.pde.FeatureBuilder org.eclipse.pde.FeatureNature ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher/build.properties ================================================ bin.includes = feature.xml ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher/feature.xml ================================================ VisualVM is a visual tool integrating several commandline JDK tools and lightweight profiling capabilities. Designed for both production and development time use, it further enhances the capability of monitoring and performance analysis for the Java SE platform. This launcher makes monitoring your eclipse based applications as easy as launching them from the IDE. Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. This code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 only, as published by the Free Software Foundation. Oracle designates this particular file as subject to the "Classpath" exception as provided by Oracle in the LICENSE file that accompanied this code. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more details (a copy is included in the LICENSE file that accompanied this code). You should have received a copy of the GNU General Public License version 2 along with this work; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA or visit www.oracle.com if you need additional information or have any questions. GNU General Public License, version 2, with the Classpath Exception The GNU General Public License (GPL) Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. One line to give the program's name and a brief idea of what it does. Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free software, and you are welcome to redistribute it under certain conditions; type 'show c' for details. The hypothetical commands 'show w' and 'show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than 'show w' and 'show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program 'Gnomovision' (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. "CLASSPATH" EXCEPTION TO THE GPL Certain source files distributed by Oracle America and/or its affiliates are subject to the following clarification and special exception to the GPL, but only where Sun has expressly included in the particular source file's header the words "Sun designates this particular file as subject to the "Classpath" exception as provided by Sun in the LICENSE file that accompanied this code." Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination. As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/.classpath ================================================ ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/.project ================================================ org.eclipse.visualvm.launcher.common org.eclipse.jdt.core.javabuilder org.eclipse.pde.ManifestBuilder org.eclipse.pde.SchemaBuilder org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/.settings/org.eclipse.jdt.core.prefs ================================================ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.5 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.source=1.5 ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/META-INF/MANIFEST.MF ================================================ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: VisualVM Launcher Plug-in Bundle-SymbolicName: org.eclipse.visualvm.launcher.common;singleton:=true Bundle-Version: 1.1.3 Bundle-Activator: org.eclipse.visualvm.launcher.Activator Bundle-Vendor: Oracle Corporation Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: com.ibm.icu.text, org.eclipse.debug.core, org.eclipse.jdt.launching Export-Package: org.eclipse.visualvm.launcher.api;version="1.1.0" Bundle-ActivationPolicy: lazy ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/build.properties ================================================ source.. = src/ output.. = bin/ bin.includes = plugin.xml,\ META-INF/,\ . ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/plugin.xml ================================================ ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/Activator.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.eclipse.visualvm.launcher; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; /** * The activator class controls the plug-in life cycle */ public class Activator extends AbstractUIPlugin { // The plug-in ID public static final String PLUGIN_ID = "org.eclipse.visualvm.launcher"; // The shared instance private static Activator plugin; /** * The constructor */ public Activator() { } /* * (non-Javadoc) * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) */ public void start(BundleContext context) throws Exception { super.start(context); plugin = this; } /* * (non-Javadoc) * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext context) throws Exception { plugin = null; super.stop(context); } /** * Returns the shared instance * * @return the shared instance */ public static Activator getDefault() { return plugin; } /** * Returns an image descriptor for the image file at the given * plug-in relative path * * @param path the path * @return the image descriptor */ public static ImageDescriptor getImageDescriptor(String path) { return imageDescriptorFromPlugin(PLUGIN_ID, path); } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/api/VisualVMHelper.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.eclipse.visualvm.launcher.api; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.StringTokenizer; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.visualvm.launcher.Activator; import org.eclipse.visualvm.launcher.preferences.PreferenceConstants; public final class VisualVMHelper { private static final String JAVA_VERSION_KEY = "java version"; private static final String OPENJDK_VERSION_KEY = "openjdk version"; private static class SpecVersion { int major, minor; public SpecVersion(String specString) { StringTokenizer st = new StringTokenizer(specString, "."); if (st.hasMoreTokens()) { major = Integer.parseInt(st.nextToken()); } if (st.hasMoreTokens()) { minor = Integer.parseInt(st.nextToken()); } } } public static long getNextID() { return System.nanoTime(); } public static String[] getJvmArgs(long id) { return new String[]{"-Dvisualvm.id=" + id}; } public static void openInVisualVM(long id) throws IOException { SpecVersion sv = getJavaVersion(); if (sv == null || (sv.major == 1 && sv.minor < 6)) { final Display d = Display.getDefault(); d.asyncExec(new Runnable() { public void run() { Shell s = new Shell(d); MessageDialog.openError(s, "VisualVM requires JDK1.6+ to run", "You are trying to launch VisualVM using an unsupported JDK.\n\nUse 'Window\\Preferences\\Run/Debug\\Launching\\VisualVM Configuration' to set the VisualVM JDK_HOME."); } }); return; } Runtime.getRuntime().exec( new String[] { Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.P_PATH), "--jdkhome", Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.P_JAVAHOME), "--openid", String.valueOf(id) }); } public static void logException(Exception ex) { IStatus s = new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getLocalizedMessage(), ex); Activator.getDefault().getLog().log(s); } private static SpecVersion getJavaVersion() { try { String javaCmd = Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.P_JAVAHOME) + File.separator + "bin" + File.separator + "java"; Process prc = Runtime.getRuntime().exec( new String[] { javaCmd, "-version" } ); String version = getJavaVersion(prc.getErrorStream()); if (version == null) { version = getJavaVersion(prc.getInputStream()); } return new SpecVersion(version); } catch (IOException e) { logException(e); } return null; } private static String getJavaVersion(InputStream is) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(is)); try { String line; while ((line = br.readLine()) != null) { if (line.startsWith(JAVA_VERSION_KEY) || line.startsWith(OPENJDK_VERSION_KEY)) { int start = line.indexOf("\""); int end = line.lastIndexOf("\""); if (start > -1 && end > -1) { return line.substring(start + 1, end); } } } } finally { br.close(); } return null; } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/preferences/LocationPreferencePage.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.eclipse.visualvm.launcher.preferences; import java.io.File; import org.eclipse.jface.preference.*; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.IWorkbench; import org.eclipse.visualvm.launcher.Activator; import org.eclipse.visualvm.launcher.resources.PreferencesMessages; /** * This class represents a preference page that * is contributed to the Preferences dialog. By * subclassing FieldEditorPreferencePage, we * can use the field support built into JFace that allows * us to create a page that is small and knows how to * save, restore and apply itself. *

* This page is used to modify preferences only. They * are stored in the preference store that belongs to * the main plug-in class. That way, preferences can * be accessed directly via the preference store. */ public class LocationPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { public LocationPreferencePage() { super(GRID); setPreferenceStore(Activator.getDefault().getPreferenceStore()); setDescription(PreferencesMessages.LocationPreferencePage_0); } /** * Creates the field editors. Field editors are abstractions of * the common GUI blocks needed to manipulate various types * of preferences. Each field editor knows how to save and * restore itself. */ public void createFieldEditors() { final boolean isWindows = System.getProperty("os.name").toUpperCase().contains("WIN"); //$NON-NLS-1$ //$NON-NLS-2$ FileFieldEditor ffe = new FileFieldEditor(PreferenceConstants.P_PATH, PreferencesMessages.LocationPreferencePage_1, getFieldEditorParent()) { @Override protected void refreshValidState() { super.refreshValidState(); if (isValid()) { boolean validated = isWindows ? getStringValue().endsWith("visualvm.exe") : getStringValue().endsWith("visualvm"); //$NON-NLS-1$ //$NON-NLS-2$ if (!validated) { setErrorMessage(PreferencesMessages.LocationPreferencePage_6); } setValid(validated); } } }; ffe.setValidateStrategy(FileFieldEditor.VALIDATE_ON_KEY_STROKE); addField(ffe); DirectoryFieldEditor dfe = new DirectoryFieldEditor(PreferenceConstants.P_JAVAHOME, PreferencesMessages.LocationPreferencePage_2, getFieldEditorParent()) { @Override protected void refreshValidState() { super.refreshValidState(); if (isValid()) { String javacPath = getStringValue() + File.separator + "bin" + File.separator + (isWindows ? "javac.exe" : "javac"); File javacFile = new File(javacPath); boolean validated = javacFile.exists() && javacFile.isFile(); if (!validated) { setErrorMessage(PreferencesMessages.LocationPreferencePage_7); } setValid(validated); } } }; dfe.setValidateStrategy(FileFieldEditor.VALIDATE_ON_KEY_STROKE); addField(dfe); } /* (non-Javadoc) * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) */ public void init(IWorkbench workbench) { } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/preferences/PreferenceConstants.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.eclipse.visualvm.launcher.preferences; /** * Constant definitions for plug-in preferences */ public class PreferenceConstants { public static final String P_PATH = "pathPreference"; public static final String P_JAVAHOME = "javaHome"; // public static final String P_BOOLEAN = "booleanPreference"; // // public static final String P_CHOICE = "choicePreference"; // // public static final String P_STRING = "stringPreference"; } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/preferences/PreferenceInitializer.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.eclipse.visualvm.launcher.preferences; import java.io.File; import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.visualvm.launcher.Activator; /** * Class used to initialize default preference values. */ public class PreferenceInitializer extends AbstractPreferenceInitializer { /* * (non-Javadoc) * * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences() */ public void initializeDefaultPreferences() { IPreferenceStore store = Activator.getDefault().getPreferenceStore(); String JAVA_HOME = System.getProperty("java.home"); if (JAVA_HOME.endsWith(File.separator + "jre")) { JAVA_HOME = JAVA_HOME.substring(0, JAVA_HOME.length() - 4); } File visualvm = new File(JAVA_HOME + File.separator + "bin" + File.separator + "jvisualvm"); if (visualvm.exists()) { store.setDefault(PreferenceConstants.P_PATH, visualvm.getAbsolutePath()); } else { store.setDefault(PreferenceConstants.P_PATH, ""); } store.setDefault(PreferenceConstants.P_JAVAHOME, JAVA_HOME); // store.setDefault(PreferenceConstants.P_BOOLEAN, true); // store.setDefault(PreferenceConstants.P_CHOICE, "choice2"); // store.setDefault(PreferenceConstants.P_STRING, // "Default value"); } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/resources/LauncherMessages.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.eclipse.visualvm.launcher.resources; import org.eclipse.osgi.util.NLS; public class LauncherMessages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.visualvm.launcher.resources.LauncherMessages";//$NON-NLS-1$ public static String VisualVMLaunchDelegate_task_1; public static String VisualVMLaunchDelegate_task_2; static { // load message values from bundle file NLS.initializeMessages(BUNDLE_NAME, LauncherMessages.class); } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/resources/LauncherMessages.properties ================================================ # Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. VisualVMLaunchDelegate_task_1=Verifying launch attributes... VisualVMLaunchDelegate_task_2=Creating source locator... ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/resources/PreferencesMessages.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.eclipse.visualvm.launcher.resources; import org.eclipse.osgi.util.NLS; public class PreferencesMessages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.visualvm.launcher.resources.PreferencesMessages"; //$NON-NLS-1$ public static String LocationPreferencePage_0; public static String LocationPreferencePage_1; public static String LocationPreferencePage_2; public static String LocationPreferencePage_6; public static String LocationPreferencePage_7; static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, PreferencesMessages.class); } private PreferencesMessages() { } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/resources/PreferencesMessages.properties ================================================ # Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. LocationPreferencePage_0=Please, select the VisualVM installation LocationPreferencePage_1=&VisualVM Executable: LocationPreferencePage_2=JDK &Home: LocationPreferencePage_6=Invalid VisualVM installation location. Make sure the file selected exists and is indeed a VisualVM LocationPreferencePage_7=VisualVM requires a full JDK to run ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.java/.classpath ================================================ ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.java/.project ================================================ org.eclipse.visualvm.launcher.java org.eclipse.jdt.core.javabuilder org.eclipse.pde.ManifestBuilder org.eclipse.pde.SchemaBuilder org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.java/.settings/org.eclipse.jdt.core.prefs ================================================ #Thu Oct 13 12:08:17 CEST 2011 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 org.eclipse.jdt.core.compiler.compliance=1.5 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.source=1.5 ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.java/META-INF/MANIFEST.MF ================================================ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: VisualVM Launcher - Java Bundle-SymbolicName: org.eclipse.visualvm.launcher.java;singleton:=true Bundle-Version: 1.1.1 Bundle-Vendor: Oracle Corporation Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Require-Bundle: org.eclipse.debug.core, org.eclipse.visualvm.launcher.common;bundle-version="1.1.3" Import-Package: org.eclipse.core.runtime, org.eclipse.jdt.internal.launching, org.eclipse.jdt.junit.launcher, org.eclipse.jdt.launching, org.eclipse.visualvm.launcher.api;version="1.0.0" ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.java/build.properties ================================================ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.xml ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.java/plugin.xml ================================================ ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.java/src/org/eclipse/visualvm/launcher/java/VisualVMAppletDelegate.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.eclipse.visualvm.launcher.java; import java.io.IOException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.jdt.internal.launching.JavaAppletLaunchConfigurationDelegate; import org.eclipse.jdt.launching.IVMRunner; import org.eclipse.visualvm.launcher.api.VisualVMHelper; @SuppressWarnings("restriction") public class VisualVMAppletDelegate extends JavaAppletLaunchConfigurationDelegate { volatile private long usedId = -1; /* (non-Javadoc) * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) */ public synchronized void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { usedId = VisualVMHelper.getNextID(); super.launch(configuration, mode, launch, monitor); } /* (non-Javadoc) * @see org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate#getVMArguments(org.eclipse.debug.core.ILaunchConfiguration) */ public String getVMArguments(ILaunchConfiguration configuration) throws CoreException { StringBuffer arguments = new StringBuffer(super.getVMArguments(configuration)); for(String arg : VisualVMHelper.getJvmArgs(usedId)) { arguments.append(" ").append(arg); } return arguments.toString(); } @Override public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException { try { VisualVMHelper.openInVisualVM(usedId); } catch (IOException e) { VisualVMHelper.logException(e); } return super.getVMRunner(configuration, mode); } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.java/src/org/eclipse/visualvm/launcher/java/VisualVMJUnitDelegate.java ================================================ package org.eclipse.visualvm.launcher.java; import java.io.IOException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate; import org.eclipse.jdt.launching.IVMRunner; import org.eclipse.visualvm.launcher.api.VisualVMHelper; public class VisualVMJUnitDelegate extends JUnitLaunchConfigurationDelegate { volatile private long usedId = -1; @Override public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { usedId = VisualVMHelper.getNextID(); super.launch(configuration, mode, launch, monitor); } @Override public String getVMArguments(ILaunchConfiguration configuration) throws CoreException { StringBuilder args = new StringBuilder(super.getVMArguments(configuration)); for(String arg : VisualVMHelper.getJvmArgs(usedId)) { args.append(" ").append(arg); } return args.toString(); } @Override public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException { try { VisualVMHelper.openInVisualVM(usedId); } catch (IOException e) { VisualVMHelper.logException(e); } return super.getVMRunner(configuration, mode); } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.java/src/org/eclipse/visualvm/launcher/java/VisualVMJavaDelegate.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.eclipse.visualvm.launcher.java; import java.io.IOException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.jdt.launching.IVMRunner; import org.eclipse.jdt.launching.JavaLaunchDelegate; import org.eclipse.visualvm.launcher.api.VisualVMHelper; public class VisualVMJavaDelegate extends JavaLaunchDelegate { volatile private long usedId = -1; @Override public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { usedId = VisualVMHelper.getNextID(); super.launch(configuration, mode, launch, monitor); } @Override public String getVMArguments(ILaunchConfiguration configuration) throws CoreException { StringBuilder args = new StringBuilder(super.getVMArguments(configuration)); for(String arg : VisualVMHelper.getJvmArgs(usedId)) { args.append(" ").append(arg); } return args.toString(); } @Override public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException { try { VisualVMHelper.openInVisualVM(usedId); } catch (IOException e) { VisualVMHelper.logException(e); } return super.getVMRunner(configuration, mode); } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.pde/.classpath ================================================ ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.pde/.project ================================================ org.eclipse.visualvm.launcher.pde org.eclipse.jdt.core.javabuilder org.eclipse.pde.ManifestBuilder org.eclipse.pde.SchemaBuilder org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.pde/.settings/org.eclipse.jdt.core.prefs ================================================ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.5 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.source=1.5 ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.pde/META-INF/MANIFEST.MF ================================================ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: VisualVM Launcher - PDE Bundle-SymbolicName: org.eclipse.visualvm.launcher.pde;singleton:=true Bundle-Version: 1.1.1 Bundle-Vendor: Oracle Corporation Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Require-Bundle: org.eclipse.visualvm.launcher.common;bundle-version="1.1.3", org.eclipse.debug.core Import-Package: org.eclipse.core.runtime, org.eclipse.jdt.junit.launcher, org.eclipse.jdt.launching, org.eclipse.pde.launching, org.eclipse.pde.ui.launcher, org.eclipse.visualvm.launcher.api ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.pde/build.properties ================================================ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.xml ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.pde/plugin.xml ================================================ ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.pde/src/org/eclipse/visualvm/launcher/pde/VisualVMJUnitPluginDelegate.java ================================================ package org.eclipse.visualvm.launcher.pde; import java.io.IOException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate; import org.eclipse.jdt.launching.IVMRunner; import org.eclipse.visualvm.launcher.api.VisualVMHelper; public class VisualVMJUnitPluginDelegate extends JUnitLaunchConfigurationDelegate { volatile private long usedId = -1; @Override public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { usedId = VisualVMHelper.getNextID(); super.launch(configuration, mode, launch, monitor); } @Override public String getVMArguments(ILaunchConfiguration configuration) throws CoreException { StringBuilder args = new StringBuilder(super.getVMArguments(configuration)); for(String arg : VisualVMHelper.getJvmArgs(usedId)) { args.append(" ").append(arg); } return args.toString(); } @Override public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException { try { VisualVMHelper.openInVisualVM(usedId); } catch (IOException e) { VisualVMHelper.logException(e); } return super.getVMRunner(configuration, mode); } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.pde/src/org/eclipse/visualvm/launcher/pde/VisualVMPDEDelegate.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.eclipse.visualvm.launcher.pde; import java.io.IOException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.jdt.launching.IVMRunner; import org.eclipse.pde.launching.EclipseApplicationLaunchConfiguration; import org.eclipse.visualvm.launcher.api.VisualVMHelper; public class VisualVMPDEDelegate extends EclipseApplicationLaunchConfiguration { volatile private long usedId = -1; @Override public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { usedId = VisualVMHelper.getNextID(); super.launch(configuration, mode, launch, monitor); } @Override public String[] getVMArguments(ILaunchConfiguration configuration) throws CoreException { String[] origArgs = super.getVMArguments(configuration); String[] visualvmArgs = VisualVMHelper.getJvmArgs(usedId); String[] newArgs = new String[origArgs.length + visualvmArgs.length]; System.arraycopy(origArgs, 0, newArgs, 0, origArgs.length); System.arraycopy(visualvmArgs, 0, newArgs, origArgs.length, visualvmArgs.length); return newArgs; } @Override public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException { try { VisualVMHelper.openInVisualVM(usedId); } catch (IOException e) { VisualVMHelper.logException(e); } return super.getVMRunner(configuration, mode); } } ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.update/.project ================================================ VisualVM Launcher Update Site org.eclipse.pde.UpdateSiteBuilder org.eclipse.pde.UpdateSiteNature ================================================ FILE: integrations/eclipse/org.eclipse.visualvm.launcher.update/site.xml ================================================ ================================================ FILE: integrations/vscode/.eslintrc.js ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* 👋 Hi! This file was autogenerated by tslint-to-eslint-config. https://github.com/typescript-eslint/tslint-to-eslint-config It represents the closest reasonable ESLint configuration to this project's original TSLint configuration. We recommend eventually switching this configuration to extend from the recommended rulesets in typescript-eslint. https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md Happy linting! 💖 */ /* eslint-disable @typescript-eslint/naming-convention */ /**@type {import('eslint').ESLint.ConfigData}*/ module.exports = { "env": { "browser": true, "es6": true, "node": true }, "parser": "@typescript-eslint/parser", "parserOptions": { "project": "tsconfig.eslint.json", "tsconfigRootDir": __dirname, "sourceType": "module" }, "plugins": [ "@typescript-eslint" ], "root": true, "rules": { "@typescript-eslint/member-delimiter-style": [ "warn", { "multiline": { "delimiter": "semi", "requireLast": true }, "singleline": { "delimiter": "semi", "requireLast": false } } ], "@typescript-eslint/naming-convention": "off", "@typescript-eslint/no-unused-expressions": "warn", "@typescript-eslint/semi": [ "warn", "always" ], "curly": "off", "eqeqeq": [ "warn", "always" ], "no-redeclare": "warn", "no-throw-literal": "warn", "no-unused-expressions": "off", "semi": "off" } }; ================================================ FILE: integrations/vscode/.gitignore ================================================ dist/ node_modules/ visualvm-vscode-*.vsix LICENSE.txt .vscode-test/ output mochawesome-report ================================================ FILE: integrations/vscode/.nvmrc ================================================ v14.16.0 ================================================ FILE: integrations/vscode/.vscode/launch.json ================================================ // A launch configuration that compiles the extension and then opens it inside a new window // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 { "version": "0.2.0", "configurations": [ { "name": "Run Extension", "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceFolder}" ], "outFiles": [ "${workspaceFolder}/out/**/*.js", "${workspaceFolder}/dist/**/*.js" ], "preLaunchTask": "npm: compile" } ] } ================================================ FILE: integrations/vscode/.vscode/settings.json ================================================ // Place your settings in this file to overwrite default and user settings. { "files.exclude": { "out": false // set this to true to hide the "out" folder with the compiled JS files }, "search.exclude": { "out": true // set this to false to include "out" folder in search results }, // Turn off tsc task auto detection since we have the necessary tasks as npm scripts "typescript.tsc.autoDetect": "off" } ================================================ FILE: integrations/vscode/.vscode/tasks.json ================================================ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format { "version": "2.0.0", "tasks": [ { "type": "npm", "script": "watch", "problemMatcher": "$tsc-watch", "isBackground": true, "presentation": { "reveal": "never" }, "group": { "kind": "build", "isDefault": true } } ] } ================================================ FILE: integrations/vscode/.vscodeignore ================================================ .vscode/** node_modules/** out/** src/** .gitignore webpack.config.js **/tsconfig*.json **/tslint.json **/*.map **/*.ts ================================================ FILE: integrations/vscode/CHANGELOG.md ================================================ # Change Log ## Version 1.0.1 * npm vulnerability fixed ## Version 1.0.0 * First stable release * [GH-598](https://github.com/oracle/visualvm/issues/598): (bugfix) VSCode Extension - Source Roots don't work in VSCode extension ## Version 0.2.0 * [GH-570](https://github.com/oracle/visualvm/issues/570): (enhancement) VSCode Extension - add custom cpu profiler filter * [GH-572](https://github.com/oracle/visualvm/issues/572): (bugfix) VSCode Extension - JDK Path with Spaces not working * [GH-576](https://github.com/oracle/visualvm/issues/576): (bugfix) VS Code Extension - Usability Issues on macOS * [GH-581](https://github.com/oracle/visualvm/issues/581): (bugfix) Conflict between vscode visualvm extension and run test with coverage ## Version 0.1.0 * Initial release ================================================ FILE: integrations/vscode/README.md ================================================ # VisualVM for VS Code This extension integrates the [VisualVM](https://visualvm.github.io) monitoring and troubleshooting tool into Visual Studio Code (VS Code). ![VisualVM View](images/visualvm_view.png) ## Features * Easy installation of VisualVM. * When starting an application from VS Code: - The application process is configured to display its folder name in VisualVM. - The application process PID is detected to invoke VisualVM actions when needed. - When started, the application process can be automatically opened in VisualVM. * Shortcuts for VisualVM actions such as Thread dump, Heap dump, Start sampling and Start flight recording are available in a dedicated view within VS Code. * The CPU Sampler filter can be automatically configured to include only application classes. * Two-way integration: the Go to Source action in VisualVM opens the source code in VS Code. ## Requirements Install the following in order to use this extension: * VisualVM 2.1+ (we recommend using the latest version of VisualVM; you can [install directly from within VS Code](#configuring-visualvm)). * Any JDK 8+ to run VisualVM and detect running processes using `jps`. Either of these Java language servers must be installed to integrate VisualVM with application startup, to support application class filtering, and to provide the Go to Source feature: * [Language Server for Java by Apache NetBeans](https://marketplace.visualstudio.com/items?itemName=ASF.apache-netbeans-java) * [Extension Pack for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack) The extension also tightly integrates with the [Tools for Micronaut® framework](https://marketplace.visualstudio.com/items?itemName=oracle-labs-graalvm.micronaut-tools) to provide the best monitoring and profiling experience. For example: * The VisualVM view can be easily displayed in the Micronaut Tools activity. * CPU Sampler is configured for the selected Graal Cloud Native (GCN) application subproject. * The Go to Source feature is configured for the selected GCN application subproject. ## Quick Start Follow these steps to start using VisualVM with VS Code: 1. Install the **VisualVM for VS Code** extension. 2. Install **Language Server for Java by Apache NetBeans** or **Extension Pack for Java** (or both). 3. Open your application sources. Make sure it is configured correctly before integrating it with VisualVM. 4. Click **Download Latest VisualVM** in the VisualVM view and complete the required steps. 5. Invoke the **Configure** action displayed for the *When started* node in the *VisualVM* view, and select **Open Process**. 6. Start the application using the **Run Without Debugging** or **Start Debugging** action. The application starts and its process is opened in VisualVM and displayed using the name of the source code folder within VS Code. The Go to Source action in the VisualVM views, such as the Heap Viewer, CPU or Memory Sampler/Profiler results, opens the associated source code within VS Code. ## Configuring VisualVM To download the latest VisualVM release from [https://visualvm.github.io](https://visualvm.github.io), use the **Download Latest VisualVM** action. Depending on the host OS, this will either download a ZIP archive or a macOS disk image (.dmg) file. The ZIP archive will be automatically extracted and registered for the extension. The macOS disk image must be installed and registered manually (see the next paragraph). If an existing local VisualVM installation is already available on the system, or after manually installing a macOS disk image, use the **Select Local VisualVM Installation** action and point to the VisualVM installation directory. The extension supports **VisualVM 2.1+**, or the corresponding GraalVM component (select the GraalVM installation directory). We recommend using the latest version of VisualVM. To manually register an existing local VisualVM installation, or to configure a specific VisualVM installation for the workspace, use the `visualvm.installation.visualvmPath` property to point to the VisualVM installation directory. Custom VisualVM startup parameters (such as `--userdir`) including VM arguments (such as `-Xmx...`) can be defined using the `visualvm.startup.visualvmParameters` property. By default, VisualVM runs using a defined/automatically found local JDK (see the [Configuring a JDK](#configuring-a-jdk) section). To define a custom JDK for running VisualVM, set the `visualvm.startup.useJdkPathForVisualvm` property to `false` and use the `--jdkhome` VisualVM startup parameter. ## Configuring a JDK The extension requires a JDK for: * Running VisualVM (if not disabled, see the [Configuring VisualVM](#configuring-visualvm) section). * To detect locally running processes using the `jps` utility, either when starting an application, or for a manual process selection. * For configuring the JDK source roots used by the `Go to Source` feature. The extension can use any JDK to run the VisualVM tool and detect Java processes. However, it should match the JDK running a monitored application in order to correctly support Go to Source for the JDK classes. The JDK is located by searching through the following properties in order: * Properties: `netbeans.jdkhome`, `java.jdt.ls.java.home`, `java.home`, `graalvm.home`. * Environment variables: `JDK_HOME`, `JAVA_HOME`. To override the JDK that was selected automatically, or to configure a specific JDK for the workspace, set the `visualvm.java.jdkPath` property to point to a local JDK installation directory (either in the VS Code Settings view, or manually in _settings.json_). ## VisualVM Actions in VS Code ### Start VisualVM * *Start VisualVM* (action in the VisualVM view toolbar) starts the VisualVM, or brings its window to the front if it is already running. ### Process Node * *Select Process*: Shows a list of all running processes available for monitoring, excluding those already being monitored. * *Show in VisualVM*: Opens the currently selected process in VisualVM, and preselects the defined view. Use the `visualvm.behavior.preselectProcessView` property to define the view to be preselected (use `Current` for no change). * *Stop Monitoring*: Clears the currently selected process, but does not stop the process or its monitoring in the VisualVM tool. ### When Started Node * *Configure*: Defines the action to be taken when a new application process is started by VS Code. When configured, the process can be automatically opened in VisualVM, and a preconfigured sampling or flight recording session can be started. > Note: The *When started* node is only displayed if the automatic application process selection is enabled (`visualvm.integration.automaticallySelectProjectProcess` property is set to `true`), and no process has been selected yet, or it has not been selected manually using the *Select Process* action. ### Thread Dump Node * *Take Thread Dump*: Takes a thread dump from a monitored process, and selects its view in VisualVM. ### Heap Dump Node * *Take Heap Dump*: Takes a heap dump from a monitored process, and selects its view in VisualVM. ### CPU Sampler Node * *Start CPU Sampling*: Starts a new CPU sampling session for a monitored process, and selects its view in VisualVM. The sampling session settings are defined by the *Filter* and *Sampling rate* subnodes. * *Take Snapshot of Sampler Results*: Takes a snapshot of the collected data, and selects its view in VisualVM. * *Stop Sampling*: Terminates the current sampling session, and selects its view in VisualVM. ### Memory Sampler Node * *Start Memory Sampling*: Starts a new memory sampling session for the monitored process, and selects its view in VisualVM. The sampling session settings are defined by the *Sampling rate* subnode. * *Take Snapshot of Sampler Results*: Takes a snapshot of the collected data, and selects its view in VisualVM. * *Stop Sampling*: Terminates the current sampling session, and selects its view in VisualVM. ### JFR Node * *Start Flight Recording*: Starts a new flight recording for a monitored process. The flight recorder preset to be used for the recording is defined by the *Settings* subnode. * *Dump Flight Recording Data*: Dumps the data for the current flight recording, and selects its view in VisualVM. * *Stop Flight Recording*: Terminates the current flight recording. ## Monitoring Multiple Processes Simultaneously Whilst monitoring multiple processes concurrently is not a typical scenario, it is supported by the VisualVM for VS Code extension. To start monitoring another process using VisualVM, start another application process using the *Run Without Debugging* or *Start Debugging* action, or use the **VisualVM: Select Process** command from the Command Palette. > Note: The *When started* node is not available for a subsequent monitored process, and its respective *Process* node is removed immediately after monitoring of the process has been stopped. ## Troubleshooting The VisualVM for VS Code extension customizes the way VS Code runs an application by adding extra VM arguments to the launch configuration. If the application process fails to start, it may be required to disable these customizations by setting the following properties to `false`: * `visualvm.integration.automaticallySelectProjectProcess` * `visualvm.integration.customizeDisplayNameForProjectProcess` The extension also controls the VisualVM startup parameters. If the VisualVM fails to start, disable or tweak the following properties: * `visualvm.startup.visualvmParameters` * `visualvm.startup.useJdkPathForVisualvm` * `visualvm.integration.enableGoToSource` In case VisualVM fails to open source code using the `Go to Source` action in VS Code, or it opens another VS Code window, configure the following property: * `visualvm.integration.visualStudioCodeParameters` For detailed analysis of any issues encountered when using the extension, see the *VisualVM for VS Code* log in the VS Code *Output* view. Additionally, see the logs of any other extensions involved, or the *Extension Host* log. For VisualVM specific troubleshooting, refer to the [VisualVM Troubleshooting Guide](https://visualvm.github.io/troubleshooting.html). ## Settings | Name | Description | Default Value | |---|---|---| | `visualvm.java.jdkPath` | Path to a local JDK installation directory (leave empty to find automatically) | | | `visualvm.startup.useJdkPathForVisualvm` | Use a defined/automatically found local JDK installation to run VisualVM (not applicable if the selected VisualVM installation is a GraalVM component) | `true` | | `visualvm.installation.visualvmPath` | Path to a local VisualVM 2.1+ installation directory (we recommend using the latest version of VisualVM) | | | `visualvm.startup.visualvmParameters` | Optional parameters for starting VisualVM (`--userdir`, `-J-Xmx`, and so on) | | | `visualvm.behavior.visualvmWindowToFront` | Bring a VisualVM window to front when a VisualVM action is invoked from within VS Code | `true` | | `visualvm.behavior.preselectProcessView` | Preselected view for a process shown in VisualVM (either the Show in VisualVM action, or the Open Process action when started) | Monitor | | `visualvm.integration.automaticallySelectProjectProcess` | Automatically select a started application process for monitoring | `true` | | `visualvm.integration.customizeDisplayNameForProjectProcess` | Configure a started application process to display its folder name in VisualVM | `true` | | `visualvm.integration.enableGoToSource` | Enable opening source code from VisualVM results in VS Code using the Go to Source action | `true` | | `visualvm.integration.visualStudioCodeParameters` | Optional parameters for invoking VS Code launcher to open source code from VisualVM (`--user-data-dir`, `--extensions-dir`, and so on) | | ## Provide Feedback or Seek Help * [Request a feature](https://github.com/oracle/visualvm/issues/new?labels=enhancement) * [File a bug](https://github.com/oracle/visualvm/issues/new?labels=bug) ## Contributing We highly appreciate any feedback! Please let us know your ideas, missing features, or bugs found. Either [file a RFE/bug](https://github.com/oracle/visualvm/issues/new/choose) or [leave us a message](https://visualvm.github.io/feedback.html). For legal reasons, we cannot accept external pull requests. See [CONTRIBUTING](https://github.com/oracle/visualvm/blob/master/CONTRIBUTING.md) for details. ## Security Please consult the [security guide](https://github.com/oracle/visualvm/blob/master/SECURITY.md) for our responsible security vulnerability disclosure process ## License Copyright (c) 2017, 2024 Oracle and/or its affiliates. Released under the GNU General Public License, version 2, with the Classpath Exception. ## Release Notes See the [CHANGELOG](https://github.com/oracle/visualvm/blob/master/integrations/vscode/CHANGELOG.md). ================================================ FILE: integrations/vscode/fixtures/test projects/demo/.gitignore ================================================ Thumbs.db .DS_Store .gradle build/ target/ out/ .micronaut/ .idea *.iml *.ipr *.iws .project .settings .classpath .factorypath ================================================ FILE: integrations/vscode/fixtures/test projects/demo/.mvn/wrapper/maven-wrapper.properties ================================================ # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you 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 # # https://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. distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar ================================================ FILE: integrations/vscode/fixtures/test projects/demo/LICENSE ================================================ Apache License Version 2.0, January 2004 https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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 https://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. ================================================ FILE: integrations/vscode/fixtures/test projects/demo/NOTICE ================================================ Copyright (c) 2024, Oracle and/or its affiliates. ================================================ FILE: integrations/vscode/fixtures/test projects/demo/README.md ================================================ ## Micronaut 4.2.1 Documentation - [User Guide](https://docs.micronaut.io/4.2.1/guide/) - [API Reference](https://docs.micronaut.io/4.2.1/api/) - [Configuration Reference](https://docs.micronaut.io/4.2.1/guide/configurationreference.html) - [Micronaut Guides](https://guides.micronaut.io/) --- - [Micronaut Maven Plugin documentation](https://micronaut-projects.github.io/micronaut-maven-plugin/latest/) ## Feature http-client documentation - [Micronaut HTTP Client documentation](https://docs.micronaut.io/latest/guide/index.html#nettyHttpClient) ## Feature maven-enforcer-plugin documentation - [https://maven.apache.org/enforcer/maven-enforcer-plugin/](https://maven.apache.org/enforcer/maven-enforcer-plugin/) ## Feature serialization-jackson documentation - [Micronaut Serialization Jackson Core documentation](https://micronaut-projects.github.io/micronaut-serialization/latest/guide/) ================================================ FILE: integrations/vscode/fixtures/test projects/demo/lib/pom.xml ================================================ 4.0.0 com.example lib 1.0-SNAPSHOT jar com.example demo-parent 1.0-SNAPSHOT jar 17 17 4.2.1-oracle-00001 4.3.1 central https://repo.maven.apache.org/maven2 gcn https://maven.oracle.com/public cloud.graal.gcn gcn-bom 4.2.1.3 pom import io.micronaut micronaut-inject compile io.micronaut.validation micronaut-validation compile io.micronaut micronaut-http-client compile io.micronaut micronaut-http-server-netty compile io.micronaut.serde micronaut-serde-jackson compile ch.qos.logback logback-classic runtime io.micronaut.test micronaut-test-junit5 test org.junit.jupiter junit-jupiter-api test org.junit.jupiter junit-jupiter-engine test ${basedir}/src/main/resources com.google.cloud.tools jib-maven-plugin ${project.name} org.apache.maven.plugins maven-enforcer-plugin org.apache.maven.plugins maven-compiler-plugin io.micronaut micronaut-http-validation ${micronaut.core.version} io.micronaut.serde micronaut-serde-processor ${micronaut.serialization.version} -Amicronaut.processing.group=com.example -Amicronaut.processing.module=lib ================================================ FILE: integrations/vscode/fixtures/test projects/demo/lib/src/main/java/com/example/.gitkeep ================================================ ================================================ FILE: integrations/vscode/fixtures/test projects/demo/lib/src/main/resources/.gitkeep ================================================ ================================================ FILE: integrations/vscode/fixtures/test projects/demo/micronaut-cli.yml ================================================ applicationType: default defaultPackage: com.example testFramework: junit sourceLanguage: java buildTool: maven features: [app-name, gcn-bom, gcn-license, gcn-oci-cloud-app, graalvm, http-client, java, java-application, junit, logback, maven, maven-enforcer-plugin, micronaut-http-validation, netty-server, properties, readme, serialization-jackson, shade] ================================================ FILE: integrations/vscode/fixtures/test projects/demo/mvnw ================================================ #!/bin/sh # ---------------------------------------------------------------------------- # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you 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 # # https://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. # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- # Apache Maven Wrapper startup batch script, version 3.1.1 # # Required ENV vars: # ------------------ # JAVA_HOME - location of a JDK home dir # # Optional ENV vars # ----------------- # MAVEN_OPTS - parameters passed to the Java VM when running Maven # e.g. to debug Maven itself, use # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 # MAVEN_SKIP_RC - flag to disable loading of mavenrc files # ---------------------------------------------------------------------------- if [ -z "$MAVEN_SKIP_RC" ] ; then if [ -f /usr/local/etc/mavenrc ] ; then . /usr/local/etc/mavenrc fi if [ -f /etc/mavenrc ] ; then . /etc/mavenrc fi if [ -f "$HOME/.mavenrc" ] ; then . "$HOME/.mavenrc" fi fi # OS specific support. $var _must_ be set to either true or false. cygwin=false; darwin=false; mingw=false case "`uname`" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home # See https://developer.apple.com/library/mac/qa/qa1170/_index.html if [ -z "$JAVA_HOME" ]; then if [ -x "/usr/libexec/java_home" ]; then JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME else JAVA_HOME="/Library/Java/Home"; export JAVA_HOME fi fi ;; esac if [ -z "$JAVA_HOME" ] ; then if [ -r /etc/gentoo-release ] ; then JAVA_HOME=`java-config --jre-home` fi fi # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi # For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then [ -n "$JAVA_HOME" ] && JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" fi if [ -z "$JAVA_HOME" ]; then javaExecutable="`which javac`" if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then # readlink(1) is not available as standard on Solaris 10. readLink=`which readlink` if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then if $darwin ; then javaHome="`dirname \"$javaExecutable\"`" javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" else javaExecutable="`readlink -f \"$javaExecutable\"`" fi javaHome="`dirname \"$javaExecutable\"`" javaHome=`expr "$javaHome" : '\(.*\)/bin'` JAVA_HOME="$javaHome" export JAVA_HOME fi fi fi if [ -z "$JAVACMD" ] ; then if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi else JAVACMD="`\\unset -f command; \\command -v java`" fi fi if [ ! -x "$JAVACMD" ] ; then echo "Error: JAVA_HOME is not defined correctly." >&2 echo " We cannot execute $JAVACMD" >&2 exit 1 fi if [ -z "$JAVA_HOME" ] ; then echo "Warning: JAVA_HOME environment variable is not set." fi # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { if [ -z "$1" ] then echo "Path not specified to find_maven_basedir" return 1 fi basedir="$1" wdir="$1" while [ "$wdir" != '/' ] ; do if [ -d "$wdir"/.mvn ] ; then basedir="$wdir" break fi # workaround for JBEAP-8937 (on Solaris 10/Sparc) if [ -d "${wdir}" ]; then wdir=`cd "$wdir/.."; pwd` fi # end of workaround done printf '%s' "$(cd "$basedir"; pwd)" } # concatenates all lines of a file concat_lines() { if [ -f "$1" ]; then echo "$(tr -s '\n' ' ' < "$1")" fi } BASE_DIR=$(find_maven_basedir "$(dirname "$0")") if [ -z "$BASE_DIR" ]; then exit 1; fi MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR if [ "$MVNW_VERBOSE" = true ]; then echo $MAVEN_PROJECTBASEDIR fi ########################################################################################## # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central # This allows using the maven wrapper in projects that prohibit checking in binary data. ########################################################################################## if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then if [ "$MVNW_VERBOSE" = true ]; then echo "Found .mvn/wrapper/maven-wrapper.jar" fi else if [ "$MVNW_VERBOSE" = true ]; then echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." fi if [ -n "$MVNW_REPOURL" ]; then wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" else wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" fi while IFS="=" read key value; do case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;; esac done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" if [ "$MVNW_VERBOSE" = true ]; then echo "Downloading from: $wrapperUrl" fi wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" if $cygwin; then wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` fi if command -v wget > /dev/null; then QUIET="--quiet" if [ "$MVNW_VERBOSE" = true ]; then echo "Found wget ... using wget" QUIET="" fi if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" else wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" fi [ $? -eq 0 ] || rm -f "$wrapperJarPath" elif command -v curl > /dev/null; then QUIET="--silent" if [ "$MVNW_VERBOSE" = true ]; then echo "Found curl ... using curl" QUIET="" fi if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L else curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L fi [ $? -eq 0 ] || rm -f "$wrapperJarPath" else if [ "$MVNW_VERBOSE" = true ]; then echo "Falling back to using Java to download" fi javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" # For Cygwin, switch paths to Windows format before running javac if $cygwin; then javaSource=`cygpath --path --windows "$javaSource"` javaClass=`cygpath --path --windows "$javaClass"` fi if [ -e "$javaSource" ]; then if [ ! -e "$javaClass" ]; then if [ "$MVNW_VERBOSE" = true ]; then echo " - Compiling MavenWrapperDownloader.java ..." fi # Compiling the Java class ("$JAVA_HOME/bin/javac" "$javaSource") fi if [ -e "$javaClass" ]; then # Running the downloader if [ "$MVNW_VERBOSE" = true ]; then echo " - Running MavenWrapperDownloader.java ..." fi ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") fi fi fi fi ########################################################################################## # End of extension ########################################################################################## MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" # For Cygwin, switch paths to Windows format before running java if $cygwin; then [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --windows "$CLASSPATH"` [ -n "$MAVEN_PROJECTBASEDIR" ] && MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` fi # Provide a "standardized" way to retrieve the CLI args that will # work with both Windows and non-Windows executions. MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" export MAVEN_CMD_LINE_ARGS WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain exec "$JAVACMD" \ $MAVEN_OPTS \ $MAVEN_DEBUG_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" ================================================ FILE: integrations/vscode/fixtures/test projects/demo/mvnw.bat ================================================ @REM ---------------------------------------------------------------------------- @REM Licensed to the Apache Software Foundation (ASF) under one @REM or more contributor license agreements. See the NOTICE file @REM distributed with this work for additional information @REM regarding copyright ownership. The ASF licenses this file @REM to you under the Apache License, Version 2.0 (the @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM @REM https://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @REM KIND, either express or implied. See the License for the @REM specific language governing permissions and limitations @REM under the License. @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- @REM Apache Maven Wrapper startup batch script, version 3.1.1 @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @REM @REM Optional ENV vars @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @REM e.g. to debug Maven itself, use @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files @REM ---------------------------------------------------------------------------- @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' @echo off @REM set title of command window title %0 @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% @REM set %HOME% to equivalent of $HOME if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") @REM Execute a user defined script before this one if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre @REM check for pre script, once with legacy .bat ending and once with .cmd ending if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* :skipRcPre @setlocal set ERROR_CODE=0 @REM To isolate internal variables from possible post scripts, we use another setlocal @setlocal @REM ==== START VALIDATION ==== if not "%JAVA_HOME%" == "" goto OkJHome echo. echo Error: JAVA_HOME not found in your environment. >&2 echo Please set the JAVA_HOME variable in your environment to match the >&2 echo location of your Java installation. >&2 echo. goto error :OkJHome if exist "%JAVA_HOME%\bin\java.exe" goto init echo. echo Error: JAVA_HOME is set to an invalid directory. >&2 echo JAVA_HOME = "%JAVA_HOME%" >&2 echo Please set the JAVA_HOME variable in your environment to match the >&2 echo location of your Java installation. >&2 echo. goto error @REM ==== END VALIDATION ==== :init @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". @REM Fallback to current working directory if not found. set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir set EXEC_DIR=%CD% set WDIR=%EXEC_DIR% :findBaseDir IF EXIST "%WDIR%"\.mvn goto baseDirFound cd .. IF "%WDIR%"=="%CD%" goto baseDirNotFound set WDIR=%CD% goto findBaseDir :baseDirFound set MAVEN_PROJECTBASEDIR=%WDIR% cd "%EXEC_DIR%" goto endDetectBaseDir :baseDirNotFound set MAVEN_PROJECTBASEDIR=%EXEC_DIR% cd "%EXEC_DIR%" :endDetectBaseDir IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig @setlocal EnableExtensions EnableDelayedExpansion for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% :endReadAdditionalConfig SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B ) @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central @REM This allows using the maven wrapper in projects that prohibit checking in binary data. if exist %WRAPPER_JAR% ( if "%MVNW_VERBOSE%" == "true" ( echo Found %WRAPPER_JAR% ) ) else ( if not "%MVNW_REPOURL%" == "" ( SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" ) if "%MVNW_VERBOSE%" == "true" ( echo Couldn't find %WRAPPER_JAR%, downloading it ... echo Downloading from: %WRAPPER_URL% ) powershell -Command "&{"^ "$webclient = new-object System.Net.WebClient;"^ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ "}"^ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ "}" if "%MVNW_VERBOSE%" == "true" ( echo Finished downloading %WRAPPER_JAR% ) ) @REM End of extension @REM Provide a "standardized" way to retrieve the CLI args that will @REM work with both Windows and non-Windows executions. set MAVEN_CMD_LINE_ARGS=%* %MAVEN_JAVA_EXE% ^ %JVM_CONFIG_MAVEN_PROPS% ^ %MAVEN_OPTS% ^ %MAVEN_DEBUG_OPTS% ^ -classpath %WRAPPER_JAR% ^ "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* if ERRORLEVEL 1 goto error goto end :error set ERROR_CODE=1 :end @endlocal & set ERROR_CODE=%ERROR_CODE% if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost @REM check for post script, once with legacy .bat ending and once with .cmd ending if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" :skipRcPost @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' if "%MAVEN_BATCH_PAUSE%"=="on" pause if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% cmd /C exit /B %ERROR_CODE% ================================================ FILE: integrations/vscode/fixtures/test projects/demo/oci/pom.xml ================================================ 4.0.0 com.example oci 1.0-SNAPSHOT ${packaging} demo-${artifactId} com.example demo-parent 1.0-SNAPSHOT jar 17 17 4.2.1-oracle-00001 frolvlad/alpine-glibc:alpine-3.16 4.3.1 netty com.example.Application central https://repo.maven.apache.org/maven2 gcn https://maven.oracle.com/public cloud.graal.gcn gcn-bom 4.2.1.3 pom import com.example lib 1.0-SNAPSHOT compile io.micronaut micronaut-http-client compile io.micronaut micronaut-http-server-netty compile io.micronaut.serde micronaut-serde-jackson compile ch.qos.logback logback-classic runtime io.micronaut.test micronaut-test-junit5 test org.junit.jupiter junit-jupiter-api test org.junit.jupiter junit-jupiter-engine test com.google.cloud.tools jib-maven-plugin ${project.name} io.micronaut.maven micronaut-maven-plugin org.apache.maven.plugins maven-enforcer-plugin org.apache.maven.plugins maven-compiler-plugin io.micronaut micronaut-http-validation ${micronaut.core.version} io.micronaut.serde micronaut-serde-processor ${micronaut.serialization.version} io.micronaut micronaut-inject -Amicronaut.processing.group=com.example -Amicronaut.processing.module=oci ================================================ FILE: integrations/vscode/fixtures/test projects/demo/oci/src/main/java/com/example/Application.java ================================================ /* * Copyright 2024 Oracle and/or its affiliates * * 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 * * https://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.example; import io.micronaut.core.annotation.NonNull; import io.micronaut.context.ApplicationContextBuilder; import io.micronaut.context.ApplicationContextConfigurer; import io.micronaut.context.annotation.ContextConfigurer; import io.micronaut.runtime.Micronaut; public class Application { @ContextConfigurer public static class Configurer implements ApplicationContextConfigurer { @Override public void configure(@NonNull ApplicationContextBuilder builder) { builder.defaultEnvironments("oraclecloud"); } } public static void main(String[] args) { Micronaut.run(Application.class, args); } } ================================================ FILE: integrations/vscode/fixtures/test projects/demo/oci/src/main/resources/application-oraclecloud.properties ================================================ micronaut.application.name=oci ================================================ FILE: integrations/vscode/fixtures/test projects/demo/oci/src/main/resources/bootstrap-oraclecloud.properties ================================================ ================================================ FILE: integrations/vscode/fixtures/test projects/demo/oci/src/main/resources/logback.xml ================================================ %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n ================================================ FILE: integrations/vscode/fixtures/test projects/demo/oci/src/test/java/com/example/OciTest.java ================================================ /* * Copyright 2024 Oracle and/or its affiliates * * 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 * * https://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.example; import io.micronaut.runtime.EmbeddedApplication; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Assertions; import jakarta.inject.Inject; @MicronautTest class OciTest { @Inject EmbeddedApplication application; @Test void testItWorks() { Assertions.assertTrue(application.isRunning()); } } ================================================ FILE: integrations/vscode/fixtures/test projects/demo/pom.xml ================================================ 4.0.0 io.micronaut.platform micronaut-parent 4.2.1-oracle-00001 central https://repo.maven.apache.org/maven2 gcn https://maven.oracle.com/public demo-parent 1.0-SNAPSHOT com.example demo pom lib oci ================================================ FILE: integrations/vscode/package.json ================================================ { "name": "visualvm-vscode", "displayName": "VisualVM for VS Code", "description": "VisualVM integration for Visual Studio Code", "version": "1.0.1-dev", "preview": false, "license": "GPLv2+CPE", "publisher": "oracle-labs-graalvm", "author": { "name": "Oracle Labs" }, "icon": "images/extension_icon.png", "homepage": "https://github.com/oracle/visualvm/blob/master/integrations/vscode/README.md", "repository": { "type": "git", "url": "https://github.com/oracle/visualvm" }, "bugs": { "url": "https://github.com/oracle/visualvm/issues" }, "engines": { "vscode": "^1.76.0" }, "categories": [ "Programming Languages", "Debuggers", "Testing", "Other" ], "keywords": [ "visualvm", "java", "performance", "profiling" ], "activationEvents": [ "*" ], "main": "./dist/extension", "contributes": { "configuration": { "type": "object", "title": "VisualVM", "properties": { "visualvm.java.jdkPath": { "type": "string", "default": "", "description": "Path to local JDK installation folder (leave empty to find automatically)", "scope": "machine-overridable" }, "visualvm.startup.useJdkPathForVisualvm": { "type": "boolean", "default": true, "description": "Use defined/automatically found local JDK installation to run VisualVM (not applicable for GraalVM component)", "scope": "machine-overridable" }, "visualvm.installation.visualvmPath": { "type": "string", "default": "", "description": "Path to local VisualVM installation folder", "scope": "machine-overridable" }, "visualvm.startup.visualvmParameters": { "type": "string", "default": "", "description": "Optional parameters for starting VisualVM (--userdir, -J-Xmx, etc.)", "scope": "machine-overridable" }, "visualvm.behavior.visualvmWindowToFront": { "type": "boolean", "default": true, "description": "Bring VisualVM window to front when invoked an action", "scope": "machine-overridable" }, "visualvm.behavior.preselectProcessView": { "type": "string", "default": "Monitor", "description": "Preselected view for a process shown in VisualVM", "enum": [ "Current", "Overview", "Monitor", "Threads", "Sampler" ], "scope": "machine-overridable" }, "visualvm.integration.automaticallySelectProjectProcess": { "type": "boolean", "default": true, "description": "Automatically select started project process for monitoring", "scope": "machine-overridable" }, "visualvm.integration.customizeDisplayNameForProjectProcess": { "type": "boolean", "default": true, "description": "Configure started project process to display its folder name in VisualVM", "scope": "machine-overridable" }, "visualvm.integration.enableGoToSource": { "type": "boolean", "default": true, "description": "Enable Go to Source integration", "scope": "machine-overridable" }, "visualvm.integration.visualStudioCodeParameters": { "type": "string", "default": "", "description": "Optional parameters for invoking VS Code launcher to open sources (--user-data-dir, --extensions-dir, etc.)", "scope": "machine-overridable" } } }, "commands": [ { "command": "visualvm.downloadVisualVM", "title": "Download Latest VisualVM", "category": "VisualVM" }, { "command": "visualvm.selectInstallation", "title": "Select Local VisualVM Installation", "category": "VisualVM" }, { "command": "visualvm.moveView", "title": "Move VisualVM View", "icon": "$(pin)", "category": "VisualVM" }, { "command": "visualvm.start", "title": "Start VisualVM", "icon": "$(run)", "category": "VisualVM", "enablement": "visualvm.initialized && !visualvm.noInstallation" }, { "command": "visualvm.configureSetting", "title": "Configure", "icon": "$(edit)", "category": "VisualVM" }, { "command": "visualvm.showProcess", "title": "Show in VisualVM", "icon": "$(eye)", "category": "VisualVM" }, { "command": "visualvm.selectProcessGlobal", "title": "Select Process", "icon": "$(search)", "category": "VisualVM" }, { "command": "visualvm.selectProcess", "title": "Select Process", "icon": "$(search)", "category": "VisualVM" }, { "command": "visualvm.clearProcess", "title": "Stop Monitoring", "icon": "$(close)", "category": "VisualVM" }, { "command": "visualvm.threadDumpTake", "title": "Take Thread Dump", "icon": "$(record)", "category": "VisualVM" }, { "command": "visualvm.heapDumpTake", "title": "Take Heap Dump", "icon": "$(record)", "category": "VisualVM" }, { "command": "visualvm.cpuSamplerStart", "title": "Start CPU Sampling", "icon": "$(play-circle)", "category": "VisualVM" }, { "command": "visualvm.cpuSamplerSnapshot", "title": "Take Snapshot of Sampler Results", "icon": "$(record)", "category": "VisualVM" }, { "command": "visualvm.cpuSamplerStop", "title": "Stop Sampling", "icon": "$(stop)", "category": "VisualVM" }, { "command": "visualvm.memorySamplerStart", "title": "Start Memory Sampling", "icon": "$(play-circle)", "category": "VisualVM" }, { "command": "visualvm.memorySamplerSnapshot", "title": "Take Snapshot of Sampler Results", "icon": "$(record)", "category": "VisualVM" }, { "command": "visualvm.memorySamplerStop", "title": "Stop Sampling", "icon": "$(stop)", "category": "VisualVM" }, { "command": "visualvm.jfrStart", "title": "Start Flight Recording", "icon": "$(play-circle)", "category": "VisualVM" }, { "command": "visualvm.jfrDump", "title": "Dump Flight Recording Data", "icon": "$(record)", "category": "VisualVM" }, { "command": "visualvm.jfrStop", "title": "Stop Flight Recording", "icon": "$(stop)", "category": "VisualVM" } ], "viewsContainers": { "activitybar": [ { "id": "visualvm", "title": "VisualVM", "icon": "resources/visualvm_icon.png" } ] }, "viewsWelcome": [ { "view": "visualvm-visualvm", "contents": "Initializing VisualVM...", "when": "!visualvm.initialized" }, { "view": "visualvm-visualvm", "contents": "Start by downloading the latest [VisualVM](https://visualvm.github.io), or select an existing local installation.\n[Download Latest VisualVM](command:visualvm.downloadVisualVM)\n[Select Local VisualVM Installation](command:visualvm.selectInstallation)\nTip: You can easily [move this view](command:visualvm.moveView) to a different location.", "when": "visualvm.noInstallation" }, { "view": "explorer-visualvm", "contents": "Initializing VisualVM...", "when": "!visualvm.initialized" }, { "view": "explorer-visualvm", "contents": "Start by downloading the latest [VisualVM](https://visualvm.github.io), or select an existing local installation.\n[Download Latest VisualVM](command:visualvm.downloadVisualVM)\n[Select Local VisualVM Installation](command:visualvm.selectInstallation)\nTip: You can easily [move this view](command:visualvm.moveView) to a different location.", "when": "visualvm.noInstallation" }, { "view": "debug-visualvm", "contents": "Initializing VisualVM...", "when": "!visualvm.initialized" }, { "view": "debug-visualvm", "contents": "Start by downloading the latest [VisualVM](https://visualvm.github.io), or select an existing local installation.\n[Download Latest VisualVM](command:visualvm.downloadVisualVM)\n[Select Local VisualVM Installation](command:visualvm.selectInstallation)\nTip: You can easily [move this view](command:visualvm.moveView) to a different location.", "when": "visualvm.noInstallation" }, { "view": "extension-micronaut-tools-visualvm", "contents": "Initializing VisualVM...", "when": "!visualvm.initialized" }, { "view": "extension-micronaut-tools-visualvm", "contents": "Start by downloading the latest [VisualVM](https://visualvm.github.io), or select an existing local installation.\n[Download Latest VisualVM](command:visualvm.downloadVisualVM)\n[Select Local VisualVM Installation](command:visualvm.selectInstallation)\nTip: You can easily [move this view](command:visualvm.moveView) to a different location.", "when": "visualvm.noInstallation" } ], "views": { "visualvm": [ { "id": "visualvm-visualvm", "name": "VisualVM", "icon": "resources/visualvm_icon.png", "when": "visualvm.view == visualvm-visualvm" } ], "explorer": [ { "id": "explorer-visualvm", "name": "VisualVM", "icon": "resources/visualvm_icon.png", "when": "visualvm.view == explorer-visualvm" } ], "debug": [ { "id": "debug-visualvm", "name": "VisualVM", "icon": "resources/visualvm_icon.png", "when": "visualvm.view == debug-visualvm" } ] }, "menus": { "commandPalette": [ { "command": "visualvm.configureSetting", "when": "false" }, { "command": "visualvm.showProcess", "when": "false" }, { "command": "visualvm.selectProcess", "when": "false" }, { "command": "visualvm.clearProcess", "when": "false" }, { "command": "visualvm.threadDumpTake", "when": "false" }, { "command": "visualvm.heapDumpTake", "when": "false" }, { "command": "visualvm.heapDumpTake", "when": "false" }, { "command": "visualvm.cpuSamplerStart", "when": "false" }, { "command": "visualvm.cpuSamplerSnapshot", "when": "false" }, { "command": "visualvm.cpuSamplerStop", "when": "false" }, { "command": "visualvm.memorySamplerStart", "when": "false" }, { "command": "visualvm.memorySamplerSnapshot", "when": "false" }, { "command": "visualvm.memorySamplerStop", "when": "false" }, { "command": "visualvm.jfrStart", "when": "false" }, { "command": "visualvm.jfrDump", "when": "false" }, { "command": "visualvm.jfrStop", "when": "false" } ], "editor/context": [], "view/title": [ { "command": "visualvm.start", "group": "navigation@1", "when": "view in visualvm.views && visualvm.initialized && !visualvm.noInstallation" }, { "command": "visualvm.moveView", "group": "navigation@2", "when": "view in visualvm.views" } ], "view/item/context": [ { "command": "visualvm.configureSetting", "when": "view in visualvm.views && viewItem in visualvm.configurableNodes", "group": "inline@1" }, { "command": "visualvm.configureSetting", "when": "view in visualvm.views && viewItem in visualvm.configurableNodes", "group": "context@1" }, { "command": "visualvm.showProcess", "when": "view in visualvm.views && viewItem == visualvm.ProcessNode.hasPid", "group": "inline@1" }, { "command": "visualvm.showProcess", "when": "view in visualvm.views && viewItem == visualvm.ProcessNode.hasPid", "group": "context@1" }, { "command": "visualvm.selectProcess", "when": "view in visualvm.views && viewItem == visualvm.ProcessNode.noProcess", "group": "inline@1" }, { "command": "visualvm.selectProcess", "when": "view in visualvm.views && viewItem == visualvm.ProcessNode.noProcess", "group": "context@1" }, { "command": "visualvm.clearProcess", "when": "view in visualvm.views && viewItem =~ /visualvm\\.ProcessNode\\.(hasId|hasPid|terminated)/", "group": "inline@4" }, { "command": "visualvm.clearProcess", "when": "view in visualvm.views && viewItem =~ /visualvm\\.ProcessNode\\.(hasId|hasPid|terminated)/", "group": "context@4" }, { "command": "visualvm.threadDumpTake", "when": "view in visualvm.views && viewItem == visualvm.ThreadDumpNode.invokable", "group": "inline@1" }, { "command": "visualvm.threadDumpTake", "when": "view in visualvm.views && viewItem == visualvm.ThreadDumpNode.invokable", "group": "context@1" }, { "command": "visualvm.heapDumpTake", "when": "view in visualvm.views && viewItem == visualvm.HeapDumpNode.invokable", "group": "inline@1" }, { "command": "visualvm.heapDumpTake", "when": "view in visualvm.views && viewItem == visualvm.HeapDumpNode.invokable", "group": "context@1" }, { "command": "visualvm.cpuSamplerStart", "when": "view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable", "group": "inline@1" }, { "command": "visualvm.cpuSamplerStart", "when": "view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable", "group": "context@1" }, { "command": "visualvm.cpuSamplerSnapshot", "when": "view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable", "group": "inline@2" }, { "command": "visualvm.cpuSamplerSnapshot", "when": "view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable", "group": "context@2" }, { "command": "visualvm.cpuSamplerStop", "when": "view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable", "group": "inline@3" }, { "command": "visualvm.cpuSamplerStop", "when": "view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable", "group": "context@3" }, { "command": "visualvm.memorySamplerStart", "when": "view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable", "group": "inline@1" }, { "command": "visualvm.memorySamplerStart", "when": "view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable", "group": "context@1" }, { "command": "visualvm.memorySamplerSnapshot", "when": "view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable", "group": "inline@2" }, { "command": "visualvm.memorySamplerSnapshot", "when": "view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable", "group": "context@2" }, { "command": "visualvm.memorySamplerStop", "when": "view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable", "group": "inline@3" }, { "command": "visualvm.memorySamplerStop", "when": "view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable", "group": "context@3" }, { "command": "visualvm.jfrStart", "when": "view in visualvm.views && viewItem == visualvm.JfrNode.invokable", "group": "inline@1" }, { "command": "visualvm.jfrStart", "when": "view in visualvm.views && viewItem == visualvm.JfrNode.invokable", "group": "context@1" }, { "command": "visualvm.jfrDump", "when": "view in visualvm.views && viewItem == visualvm.JfrNode.invokable", "group": "inline@2" }, { "command": "visualvm.jfrDump", "when": "view in visualvm.views && viewItem == visualvm.JfrNode.invokable", "group": "context@2" }, { "command": "visualvm.jfrStop", "when": "view in visualvm.views && viewItem == visualvm.JfrNode.invokable", "group": "inline@3" }, { "command": "visualvm.jfrStop", "when": "view in visualvm.views && viewItem == visualvm.JfrNode.invokable", "group": "context@3" } ] } }, "vsce": { "baseImagesUrl": "https://github.com/oracle/visualvm/raw/master/integrations/vscode" }, "config": { "winBuildPath": ".\\node_modules\\.bin\\vsce", "unixBuildPath": "./node_modules/.bin/vsce", "buildCmd": "package --allow-star-activation --no-update-package-json" }, "scripts": { "vscode:prepublish": "copyfiles -f ../../LICENSE.txt . && cross-env NODE_OPTIONS='--max-old-space-size=8192' webpack --mode production", "compile": "webpack --mode development", "info": "webpack --display-modules", "watch": "webpack --mode development --watch", "prebuild": "npm install", "build": "cross-os build", "lint": "eslint src --ext ts", "pretest": "tsc -p ./", "watch-tests": "tsc -watch -p ./", "test": "cross-env GLOBAL_AGENT_NO_PROXY=$no_proxy GLOBAL_AGENT_HTTP_PROXY=$http_proxy node ./dist/test/runTest.js" }, "cross-os": { "build": { "linux": "$npm_package_config_unixBuildPath $npm_package_config_buildCmd `[ -z ${BUILD_NUMBER} ] && echo \"${npm_package_version}\" || echo \"${npm_package_version}-${BUILD_NUMBER}\"`", "darwin": "$npm_package_config_unixBuildPath $npm_package_config_buildCmd `[ -z ${BUILD_NUMBER} ] && echo \"${npm_package_version}\" || echo \"${npm_package_version}-${BUILD_NUMBER}\"`", "win32": "%npm_package_config_winBuildPath% %npm_package_config_buildCmd%" } }, "dependencies": { "decompress": "^4.2.1" }, "devDependencies": { "@types/decompress": "^4.2.3", "@types/glob": "^8.0.1", "@types/isomorphic-fetch": "^0.0.36", "@types/node": "^14.16.0", "@types/mocha": "^10.0.6", "@types/vscode": "^1.76.0", "@typescript-eslint/eslint-plugin": "^5.54.1", "@typescript-eslint/parser": "^5.54.1", "@vscode/codicons": "0.0.20", "@vscode/test-electron": "^2.2.3", "@vscode/vsce": "^2.15.0", "copyfiles": "^2.4.1", "cross-env": "^7.0.3", "cross-os": "^1.5.0", "encoding": "^0.1.13", "eslint": "^8.35.0", "eslint-webpack-plugin": "^4.0.0", "glob": "^8.1.0", "global-agent": "^3.0.0", "mocha": "^10.1.0", "mochawesome": "^7.1.3", "node-abort-controller": "^3.1.1", "ts-loader": "^9.4.2", "typescript": "^4.9.5", "webpack": "^5.94.0", "webpack-cli": "^4.10.0" } } ================================================ FILE: integrations/vscode/src/commands.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ export const COMMAND_DOWNLOAD_LATEST_VISUALVM = 'visualvm.downloadVisualVM'; export const COMMAND_SELECT_INSTALLATION = 'visualvm.selectInstallation'; export const COMMAND_SELECT_INSTALLATION_NAME = 'Select Local VisualVM Installation'; export const COMMAND_START_VISUALVM = 'visualvm.start'; export const COMMAND_MOVE_VIEW = 'visualvm.moveView'; export const COMMAND_MOVE_VIEW_NAME = 'Move VisualVM View'; export const COMMAND_SELECT_PROCESS_GLOBAL = 'visualvm.selectProcessGlobal'; export const COMMAND_SELECT_PROCESS = 'visualvm.selectProcess'; export const COMMAND_CLEAR_PROCESS = 'visualvm.clearProcess'; export const COMMAND_CONFIGURE_SETTING = 'visualvm.configureSetting'; export const COMMAND_OPEN_PROCESS = 'visualvm.showProcess'; export const COMMAND_THREADDUMP_TAKE = 'visualvm.threadDumpTake'; export const COMMAND_HEAPDUMP_TAKE = 'visualvm.heapDumpTake'; export const COMMAND_CPU_SAMPLER_START = 'visualvm.cpuSamplerStart'; export const COMMAND_CPU_SAMPLER_SNAPSHOT = 'visualvm.cpuSamplerSnapshot'; export const COMMAND_CPU_SAMPLER_STOP = 'visualvm.cpuSamplerStop'; export const COMMAND_MEMORY_SAMPLER_START = 'visualvm.memorySamplerStart'; export const COMMAND_MEMORY_SAMPLER_SNAPSHOT = 'visualvm.memorySamplerSnapshot'; export const COMMAND_MEMORY_SAMPLER_STOP = 'visualvm.memorySamplerStop'; export const COMMAND_JFR_START = 'visualvm.jfrStart'; export const COMMAND_JFR_DUMP = 'visualvm.jfrDump'; export const COMMAND_JFR_STOP = 'visualvm.jfrStop'; ================================================ FILE: integrations/vscode/src/download.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as os from 'os'; import * as fs from 'fs'; import * as path from 'path'; import * as https from 'https'; import * as process from 'process'; import * as install from './install'; import * as commands from './commands'; import * as visualvm from './visualvm'; import * as logUtils from './logUtils'; const VISUALVM_URL: string = 'https://api.github.com'; const VISUALVM_RELEASES_URL: string = VISUALVM_URL + '/repos/oracle/visualvm/releases'; const EXT_ID = 'oracle-labs-graalvm.visualvm-vscode'; const VSCODE_AGENT = `VSCode/${vscode.version}`; const SYSTEM_INFO = `${process.platform} ${process.arch}`; const EXT_AGENT = `${EXT_ID}/${vscode.extensions.getExtension(EXT_ID)?.packageJSON.version}`; const USER_AGENT = `${VSCODE_AGENT} (${SYSTEM_INFO}) ${EXT_AGENT}`; export function initialize(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_DOWNLOAD_LATEST_VISUALVM, () => { downloadLatestVisualVM(); })); } export async function downloadLatestVisualVM(predefinedPath?: string) { logUtils.logInfo('[download] Requested to download latest VisualVM'); const folder = predefinedPath ? predefinedPath : await selectFolder(); if (!folder) { logUtils.logInfo('[download] Destination folder selection canceled'); return; } logUtils.logInfo(`[download] Selected destination folder ${folder}`); let releaseMetadata: any | undefined = undefined; await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: 'Searching for the latest VisualVM...' }, async () => { releaseMetadata = await getReleaseMetadata(); }); if (!releaseMetadata) { return; } const releaseName = releaseMetadata.name; logUtils.logInfo(`[download] Found latest release: ${releaseName}`); const releaseAsset = getReleaseAsset(releaseMetadata); if (!releaseAsset) { return; } const url = releaseAsset.browser_download_url; if (!url) { logUtils.logError(`[download] Could not find download link for ${releaseName}`); const msg = new vscode.MarkdownString(`Could not find download link. Download VisualVM manually from [${visualvm.VISUALVM_HOMEPAGE}](${visualvm.VISUALVM_HOMEPAGE}), and use the ${commands.COMMAND_SELECT_INSTALLATION_NAME} action to start using it.`); vscode.window.showErrorMessage(msg.value); return; } logUtils.logInfo(`[download] Found download link: ${url}`); if (process.platform !== 'darwin') { const parsedName = path.parse(releaseAsset.name); const targetFolder = path.join(folder, parsedName.name); if (fs.existsSync(targetFolder)) { // TODO: should check if directory? logUtils.logWarning(`[download] Found existing directory ${targetFolder} while verifying download of ${releaseName}`); const msg = `${releaseName} seems to be already installed in the selected folder. Download anyway?`; const downloadOption = 'Download'; const openOption = 'Open Folder'; const cancelOption = 'Cancel'; const selected = await vscode.window.showWarningMessage(msg, downloadOption, openOption, cancelOption); if (selected !== downloadOption) { if (selected === openOption) { vscode.commands.executeCommand('revealFileInOS', vscode.Uri.file(targetFolder)); } return; } } } const file = uniquePath(folder, releaseAsset.name); logUtils.logInfo(`[download] Downloading ${releaseName} to ${file}`); const result = await download(url, file, releaseName); if (!result) { return; } logUtils.logInfo(`[download] Downloaded ${releaseName} to ${file}`); if (process.platform === 'darwin') { await install.installDiskImage(result, releaseName); // TODO: add await return result; } else { const parsedName = path.parse(releaseAsset.name); const targetFolder = uniquePath(folder, parsedName.name); await install.installZipArchive(result, targetFolder, releaseName); // TODO: add await return targetFolder; } } async function selectFolder(): Promise { const selectedFolder = await vscode.window.showOpenDialog({ title: 'Download VisualVM: Select Folder', canSelectFiles: false, canSelectFolders: true, canSelectMany: false, defaultUri: vscode.Uri.file(os.homedir()), openLabel: process.platform === 'darwin' ? 'Select Target Folder' : 'Select' }); return selectedFolder?.length === 1 ? selectedFolder[0].fsPath : undefined; } export async function getReleaseMetadata(): Promise { logUtils.logInfo('[download] Searching for latest VisualVM release'); const USER_AGENT_OPTIONS: https.RequestOptions = { headers: { 'User-Agent': USER_AGENT } // TODO: add support for 'Accept-Encoding': 'gzip'; }; try { const rawReleases = await getWithOptions(VISUALVM_RELEASES_URL, USER_AGENT_OPTIONS, /^application\/json/); if (rawReleases) { const releases = JSON.parse(rawReleases); if (Array.isArray(releases)) { for (const release of releases) { // should be sorted latest first if (release.draft === false) { return release; } } } } } catch (err) { logUtils.logError(`[download] Could not find latest VisualVM release: ${err}`); if ((err as any)?.code === 'ENOTFOUND' || (err as any)?.code === 'ETIMEDOUT') { vscode.window.showErrorMessage('Cannot get data from server. Check your connection and verify proxy settings.'); } else { vscode.window.showErrorMessage(`Cannot get data from server: ${(err as any)?.message}`); } } return undefined; } function getReleaseAsset(releaseMetadata: any): any | undefined { const releaseName = releaseMetadata.name; // VisualVM 2.1.7 if (!releaseName) { logUtils.logError('[download] Could not resolve release name'); return undefined; } const releaseVersion = String(releaseName).split(' ').pop(); // 2.1.7 if (!releaseVersion) { logUtils.logError(`[download] Could not determine release version from ${releaseName}`); return undefined; } const releaseKey = releaseVersion.replace(/\./g, ''); // 217 const fileName = process.platform === 'darwin' ? `VisualVM_${releaseKey}.dmg` : `visualvm_${releaseKey}.zip`; if (!Array.isArray(releaseMetadata.assets)) { logUtils.logError('[download] Could not recognize release assets structure'); return undefined; } for (const asset of releaseMetadata.assets) { if (asset.name === fileName) { logUtils.logInfo(`[download] Found release asset for ${fileName}`); return asset; } } logUtils.logError('[download] Could not find release asset'); return undefined; } async function getWithOptions(url: string, options: https.RequestOptions, contentTypeRegExp: RegExp): Promise { return new Promise((resolve, reject) => { https.get(url, options, res => { const { statusCode } = res; const contentType = res.headers['content-type'] || ''; let error; if (statusCode !== 200) { error = new Error(`Request Failed.\nStatus Code: ${statusCode}`); } else if (!contentTypeRegExp.test(contentType)) { error = new Error(`Invalid content-type received ${contentType}`); } if (error) { res.resume(); reject(error); } else { let rawData: string = ''; res.on('data', chunk => { rawData += chunk; }); res.on('end', () => { resolve(rawData); }); } }).on('error', e => { reject(e); }).end(); }); } async function download(url: string, file: string, name: string): Promise { try { return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: `Downloading ${name}...`, cancellable: true }, (progress, token) => { return new Promise((resolve, reject) => { const fileStream: fs.WriteStream = fs.createWriteStream(file); const request = function (url: string) { https.get(url, res => { const { statusCode } = res; if (statusCode === 302) { if (res.headers.location) { request(res.headers.location); } } else { let error; const contentType = res.headers['content-type'] || ''; const length = parseInt(res.headers['content-length'] || '0'); if (statusCode !== 200) { error = new Error(`Request Failed.\nStatus Code: ${statusCode}`); } else if (!/^application\/(octet-stream|x-gtar|zip)/.test(contentType)) { error = new Error(`Invalid content-type received ${contentType}`); } if (error) { reject(error); res.resume(); fileStream.end(); } else { token.onCancellationRequested(() => { reject(); res.destroy(); fileStream.end(); fs.unlinkSync(file); }); res.pipe(fileStream); if (length) { const percent = length / 100; let counter = 0; let progressCounter = 0; res.on('data', chunk => { counter += chunk.length; let f = Math.floor(counter / percent); if (f > progressCounter) { progress.report({ increment: f - progressCounter }); progressCounter = f; } }); } res.on('end', () => { resolve(file); // file.end(); // NOTE: called by 'res.pipe(file);' }); } } }).on('error', e => { reject(e); fileStream.end(); }); }; request(url); }); }); } catch (err) { if (err) { logUtils.logError(`[download] Download of ${name} from ${url} to ${file} failed: ${err}`); vscode.window.showErrorMessage(`Error downloading ${name}: ${(err as any)?.message}`); } else { logUtils.logInfo(`[download] Download of ${name} canceled`); // canceled } return undefined; } } function uniquePath(folder: string, name: string) { let uniquePath = path.join(folder, name); if (fs.existsSync(uniquePath)) { const parsedName = path.parse(name); const namePart = parsedName.name; const extPart = parsedName.ext; let suffix = 0; do { uniquePath = path.join(folder, `${namePart}_${++suffix}${extPart}`); } while (fs.existsSync(uniquePath)); } return uniquePath; } ================================================ FILE: integrations/vscode/src/extension.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as presets from './presets'; // must be imported first import * as view from './view'; import * as visualvm from './visualvm'; import * as nodes from './nodes'; import * as monitoredProcesses from './monitoredProcesses'; import * as download from './download'; import * as logUtils from './logUtils'; export function activate(context: vscode.ExtensionContext) { logUtils.registerExtensionForLogging(context); logUtils.logInfo('[extension] Activating extension'); presets.initialize(context); // must be initialized first view.initialize(context); visualvm.initialize(context); nodes.initialize(context); monitoredProcesses.initialize(context); download.initialize(context); logUtils.logInfo('[extension] Extension activated'); } ================================================ FILE: integrations/vscode/src/install.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as fs from 'fs'; import * as path from 'path'; import * as decompress from 'decompress'; import * as visualvm from './visualvm'; import * as commands from './commands'; import * as logUtils from './logUtils'; export async function installZipArchive(zipFile: string, targetDir: string, name: string, deleteZipFile: boolean = true) { logUtils.logInfo(`[install] Installing ${name} zip archive ${zipFile} to ${targetDir}`); try { await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: `Extracting ${name}...` }, async () => { try { logUtils.logInfo(`[install] Extracting zip archive ${zipFile} to ${targetDir}`); await decompress(zipFile, targetDir, { strip: 1 }); } catch (err) { logUtils.logError(`[install] Failed to extract zip archive ${zipFile} to ${targetDir}: ${err}`); vscode.window.showErrorMessage(`Failed to extract ${name}: ${err}`); throw(err); } // This is to prevent VisualVM startup failure - happens for identical .lastModified timestamps in different installation paths touchFile(path.join(targetDir, 'platform', '.lastModified')); touchFile(path.join(targetDir, 'visualvm', '.lastModified')); if (deleteZipFile) { try { logUtils.logInfo(`[install] Deleting zip archive ${zipFile}`); fs.unlinkSync(zipFile); } catch (err) { logUtils.logWarning(`[install] Failed to delete zip archive ${zipFile}: ${err}`); const msg = `Failed to delete downloaded ${name} archive ${zipFile}: ${err}`; const openOption = 'Open File Location'; const selected = await vscode.window.showWarningMessage(msg, openOption); if (selected === openOption) { vscode.commands.executeCommand('revealFileInOS', vscode.Uri.file(zipFile)); } throw(err); } } }); await visualvm.select(targetDir); } catch (err) { logUtils.logError(`[install] Failed to install zip archive ${zipFile} to ${targetDir}: ${err}`); } } function touchFile(path: string): boolean { const date = new Date(); try { logUtils.logInfo(`[install] Resetting times for ${path}`); fs.utimesSync(path, date, date); return true; } catch (err) { logUtils.logWarning(`[install] Failed to reset times for ${path}: ${err}`); } return false; } export async function installDiskImage(dmgFile: string, name: string, _deleteDmgFile: boolean = true) { logUtils.logInfo(`[install] Request to manually install ${name} disk image ${dmgFile}`); const msg = `${name} disk image has been downloaded to the selected folder. Install it and use the ${commands.COMMAND_SELECT_INSTALLATION_NAME} action to start using it.`; const openOption = 'Open File Location'; const selected = await vscode.window.showInformationMessage(msg, openOption); if (selected === openOption) { vscode.commands.executeCommand('revealFileInOS', vscode.Uri.file(dmgFile)); } } ================================================ FILE: integrations/vscode/src/jdk.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as os from 'os'; import * as fs from 'fs'; import * as path from 'path'; import * as process from 'process'; import * as logUtils from './logUtils'; // Paths to JDK used in settings.json const VISUALVM_JDK_PATH_KEY = 'visualvm.java.jdkPath'; const NETBEANS_JDK_PATH_KEY = 'netbeans.jdkhome'; const JDT_JS_JDK_PATH_KEY = 'java.jdt.ls.java.home'; const JDK_JDK_PATH_KEY = 'java.home'; const GRAALVM_PATH_KEY = 'graalvm.home'; const JDK_KEYS = [ VISUALVM_JDK_PATH_KEY, NETBEANS_JDK_PATH_KEY, JDT_JS_JDK_PATH_KEY, JDK_JDK_PATH_KEY, GRAALVM_PATH_KEY ]; // Paths to JDK used in evironment const JDK_HOME_ENV_VAR = 'JDK_HOME'; const JAVA_HOME_ENV_VAR = 'JAVA_HOME'; const JDK_ENV_VARS = [ JDK_HOME_ENV_VAR, JAVA_HOME_ENV_VAR ]; export async function getPath(interactive: boolean = true): Promise { logUtils.logInfo('[jdk] Getting a JDK'); const configuration = vscode.workspace.getConfiguration(); for (const jdkPathKey of JDK_KEYS) { const jdkPath = configuration.get(jdkPathKey); if (jdkPath) { logUtils.logInfo(`[jdk] Resolved path for setting ${jdkPathKey}: ${jdkPath}`); if (isSupportedJDK(jdkPath)) { logUtils.logInfo(`[jdk] Verified path for setting ${jdkPathKey}: ${jdkPath}`); return jdkPath; } } } for (const jdkEnvVar of JDK_ENV_VARS) { const jdkPath = process.env[jdkEnvVar]; if (jdkPath) { logUtils.logInfo(`[jdk] Resolved path for environment variable ${jdkEnvVar}: ${jdkPath}`); if (isSupportedJDK(jdkPath)) { logUtils.logInfo(`[jdk] Verified path for environment variable ${jdkEnvVar}: ${jdkPath}`); return jdkPath; } } } logUtils.logInfo('[jdk] No supported JDK found'); if (interactive) { logUtils.logInfo('[jdk] Selecting JDK installation'); const jdkPath = await select(); if (jdkPath) { logUtils.logInfo(`[jdk] Selected JDK installation: ${jdkPath}`); if (isSupportedJDK(jdkPath)) { logUtils.logInfo(`[jdk] Verified selected JDK installation: ${jdkPath}`); await vscode.workspace.getConfiguration().update(VISUALVM_JDK_PATH_KEY, jdkPath, vscode.ConfigurationTarget.Global); return jdkPath; } else { logUtils.logError(`[jdk] Selected JDK installation is invalid: ${jdkPath}`); vscode.window.showErrorMessage(`Selected JDK installation is invalid: ${jdkPath}`); } } else { logUtils.logInfo('[jdk] JDK installation selection canceled'); } } return undefined; } async function select(): Promise { const selectedJDKUri = await vscode.window.showOpenDialog({ title: 'Select Local JDK Installation Folder', canSelectFiles: false, canSelectFolders: true, canSelectMany: false, defaultUri: vscode.Uri.file(os.homedir()), openLabel: process.platform !== 'darwin' ? 'Select JDK Installation' : 'Select' }); const jdkPath = selectedJDKUri?.length === 1 ? selectedJDKUri[0].fsPath : undefined; if (jdkPath && process.platform === 'darwin') { const jdkHomePath = path.join(jdkPath, 'Contents', 'Home'); if (fs.existsSync(jdkHomePath)) { return jdkHomePath; } } return jdkPath; } export function isSupportedJDK(jdkPath: string): boolean { return !!getJpsPath(jdkPath); } export function getJpsPath(jdkPath: string): string | undefined { const jdkJpsPath = path.join(jdkPath, 'bin', process.platform === 'win32' ? 'jps.exe' : 'jps'); if (!fs.existsSync(jdkJpsPath)) { logUtils.logWarning(`[jdk] Required jps binary does not exist (JRE only?): ${jdkJpsPath}`); return undefined; } if (!fs.statSync(jdkJpsPath).isFile()) { logUtils.logWarning(`[jdk] Required jps binary is not a file: ${jdkJpsPath}`); return undefined; } return jdkJpsPath; } export function getPackages(): string { let ret = 'java.**, javax.**, jdk.**'; ret += ', org.graalvm.**'; ret += ', com.sun.**, sun.**, sunw.**'; ret += ', org.omg.CORBA.**, org.omg.CosNaming.**, COM.rsa.**'; if (process.platform === 'darwin') { ret += ', apple.laf.**, apple.awt.**, com.apple.**'; } return ret; } export async function getSources(jdkPath: string): Promise<{ path: string; modular: boolean } | undefined> { const modularJdkSrc = path.join(jdkPath, 'lib', 'src.zip'); if (fs.existsSync(modularJdkSrc)) { return { path: modularJdkSrc, modular: true }; } const jdkSrc = path.join(jdkPath, 'src.zip'); if (fs.existsSync(jdkSrc)) { return { path: jdkSrc, modular: false }; } return undefined; } ================================================ FILE: integrations/vscode/src/logUtils.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; let LOG_OUTPUT: vscode.LogOutputChannel; export function registerExtensionForLogging(context: vscode.ExtensionContext) { if (!LOG_OUTPUT) { LOG_OUTPUT = vscode.window.createOutputChannel(context.extension.packageJSON.displayName, { log: true }); } } export function logTrace(record: string) { if (!LOG_OUTPUT) { throw new Error("Extension isn't registered for logging."); } LOG_OUTPUT.trace(record); } export function logDebug(record: string) { if (!LOG_OUTPUT) { throw new Error("Extension isn't registered for logging."); } LOG_OUTPUT.debug(record); } export function logInfo(record: string) { if (!LOG_OUTPUT) { throw new Error("Extension isn't registered for logging."); } LOG_OUTPUT.info(record); } export function logWarning(record: string) { if (!LOG_OUTPUT) { throw new Error("Extension isn't registered for logging."); } LOG_OUTPUT.warn(record); } export function logError(record: string) { if (!LOG_OUTPUT) { throw new Error("Extension isn't registered for logging."); } LOG_OUTPUT.error(record); } export function logAndThrow(record: string, errFnc?: (err: Error) => Error) { if (!LOG_OUTPUT) { throw new Error("Extension isn't registered for logging."); } LOG_OUTPUT.error(record); const err = new Error(record); throw errFnc ? errFnc(err) : err; } ================================================ FILE: integrations/vscode/src/monitoredProcesses.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as process from 'process'; import * as jdk from './jdk'; import * as parameters from './parameters'; import * as runningProcesses from './runningProcesses'; import * as logUtils from './logUtils'; export const AUTO_SELECT_PROJECT_PROCESS_KEY = 'visualvm.integration.automaticallySelectProjectProcess'; export const CUSTOMIZE_PROJECT_PROCESS_DISPLAYNAME_KEY = 'visualvm.integration.customizeDisplayNameForProjectProcess'; export type OnChanged = (added: MonitoredProcess | undefined, removed: MonitoredProcess | undefined, target: any | undefined) => void; export type OnPidChanged = () => void; const ON_CHANGED_LISTENERS: OnChanged[] = []; export function onChanged(listener: OnChanged) { ON_CHANGED_LISTENERS.push(listener); } function notifyChanged(added: MonitoredProcess | undefined, removed: MonitoredProcess | undefined, target?: any) { for (const listener of ON_CHANGED_LISTENERS) { listener(added, removed, target); } } export function initialize(context: vscode.ExtensionContext) { const configurationProvider = new ConfigurationProvider(); context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('java8+', configurationProvider)); context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('java+', configurationProvider)); context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('java', configurationProvider)); context.subscriptions.push(vscode.debug.onDidStartDebugSession(session => { debugSessionStarted(session); })); context.subscriptions.push(vscode.debug.onDidTerminateDebugSession(session => { debugSessionTerminated(session); })); logUtils.logInfo('[monitoredProcess] Initialized'); } const MONITORED_PROCESSES: MonitoredProcess[] = []; export function add(running: runningProcesses.RunningProcess, target?: any): MonitoredProcess | undefined { logUtils.logInfo(`[monitoredProcess] Adding running process ${running.displayName}@${running.pid}`); const monitoredRunning = getPids(); if (!monitoredRunning.includes(running.pid)) { const monitoredProcess = new MonitoredProcess(running.pid.toString(), running.displayName, undefined, running.pid); return addMonitored(monitoredProcess, target); } else { logUtils.logWarning(`[monitoredProcess] Process already tracked: ${running.displayName}@${running.pid}`); return undefined; } } function addMonitored(monitored: MonitoredProcess, target?: any): MonitoredProcess { logUtils.logInfo(`[monitoredProcess] Started tracking process ${monitored.displayName}@${monitored.id}`); MONITORED_PROCESSES.push(monitored); notifyChanged(monitored, undefined, target); return monitored; } export function remove(monitored: MonitoredProcess, target?: any): MonitoredProcess | undefined { logUtils.logInfo(`[monitoredProcess] Removing monitored process ${monitored.displayName}@${monitored.id}`); const index = MONITORED_PROCESSES.indexOf(monitored); if (index > -1) { logUtils.logInfo(`[monitoredProcess] Stopped tracking process ${monitored.displayName}@${monitored.id}`); MONITORED_PROCESSES.splice(index, 1); monitored.release(); notifyChanged(undefined, monitored, target); return monitored; } else { logUtils.logWarning(`[monitoredProcess] Process not tracked: ${monitored.displayName}@${monitored.id}`); return undefined; } } export function getPids(): number[] { const pids: number[] = []; for (const process of MONITORED_PROCESSES) { const pid = process.getPid(); if (pid !== undefined && pid !== null) { pids.push(pid); } } return pids; } function debugSessionStarted(session: vscode.DebugSession) { const vmArgs = session.configuration.vmArgs; if (vmArgs) { for (const monitoredProcess of MONITORED_PROCESSES) { const id = parameters.vmArgId(monitoredProcess.id); if (vmArgs.includes(id)) { logUtils.logInfo(`[monitoredProcess] Session started for process ${monitoredProcess.displayName}@${monitoredProcess.id}`); monitoredProcess.sessionStarted(session); break; } } } } function debugSessionTerminated(session: vscode.DebugSession) { for (const monitoredProcess of MONITORED_PROCESSES) { if (monitoredProcess.isSession(session)) { logUtils.logInfo(`[monitoredProcess] Session terminated for process ${monitoredProcess.displayName}@${monitoredProcess.id}`); remove(monitoredProcess); break; } } } export class MonitoredProcess { readonly id: string; readonly displayName: string; readonly workspaceFolder: vscode.WorkspaceFolder | undefined; readonly isManuallySelected: boolean; private pid: number | undefined | null = undefined; private session: vscode.DebugSession | undefined = undefined; constructor(id: string, displayName: string, workspaceFolder?: vscode.WorkspaceFolder, pid?: number) { this.id = id; this.displayName = displayName; this.workspaceFolder = workspaceFolder; this.pid = pid; this.isManuallySelected = pid !== undefined; } isSession(session: vscode.DebugSession) { return this.session === session; } sessionStarted(session: vscode.DebugSession) { this.session = session; if (this.pid === undefined) { const onFound = (pid: number) => { this.pid = pid; this.notifyPidChanged(); logUtils.logInfo(`[monitoredProcess] Found running process ${this.displayName}@${this.id}: pid=${pid}`); }; const onTimeout = () => { logUtils.logInfo(`[monitoredProcess] Timed out waiting for process ${this.displayName}@${this.id}`); remove(this); }; runningProcesses.searchByParameter(parameters.vmArgId(this.id), onFound, onTimeout); } } getPid(interactive: boolean = true): number | undefined | null { // undefined - not discovered yet, null - terminated if (this.pid) { try { process.kill(this.pid, 0); } catch (err) { logUtils.logInfo(`[monitoredProcess] Detected terminated process ${this.displayName}@${this.id}`); this.release(); if (interactive) { vscode.window.showWarningMessage(`Process ${this.displayName} already terminated.`); } // Must be delayed to not break iterating MONITORED_PROCESSES[].getPid() setTimeout(() => { remove(this); }, 0); } } return this.pid; } release() { if (this.pid !== null) { logUtils.logInfo(`[monitoredProcess] Releasing process ${this.displayName}@${this.id}`); if (this.pid === undefined) { runningProcesses.stopSearching(parameters.vmArgId(this.id)); } this.pid = null; this.notifyPidChanged(); this.ON_PID_CHANGED_LISTENERS.length = 0; } this.session = undefined; } private ON_PID_CHANGED_LISTENERS: OnPidChanged[] = []; onPidChanged(listener: OnPidChanged) { this.ON_PID_CHANGED_LISTENERS.push(listener); } private notifyPidChanged() { for (const listener of this.ON_PID_CHANGED_LISTENERS) { listener(); } } } function displayName(displayName: string | undefined): string { return displayName = displayName || 'VS Code Project'; } class ConfigurationProvider implements vscode.DebugConfigurationProvider { resolveDebugConfiguration/*WithSubstitutedVariables?*/(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult { logUtils.logInfo(`[monitoredProcess] VS Code starting new process${folder ? ' for folder ' + folder.name : ''}`); return new Promise(async resolve => { const name = displayName(folder?.name); const vmArgs: string[] = []; if (vscode.workspace.getConfiguration().get(CUSTOMIZE_PROJECT_PROCESS_DISPLAYNAME_KEY)) { logUtils.logInfo(`[monitoredProcess] Will customize display name: ${name}`); vmArgs.push(parameters.vmArgDisplayName(name)); } if (vscode.workspace.getConfiguration().get(AUTO_SELECT_PROJECT_PROCESS_KEY)) { const jdkPath = await jdk.getPath(false); const jpsPath = jdkPath ? jdk.getJpsPath(jdkPath) : undefined; if (jpsPath) { runningProcesses.setJpsPath(jpsPath); const id = Date.now().toString(); const process = new MonitoredProcess(id, name, folder); logUtils.logInfo(`[monitoredProcess] Will select the process with id: ${id}`); addMonitored(process); vmArgs.push(parameters.vmArgId(id)); } else { logUtils.logWarning('[monitoredProcess] Will not select the process, no JDK/jps found'); const reason = jdkPath ? 'The JDK for VisualVM is not valid.' : 'No JDK for VisualVM found.'; const msg = `${reason} The started process will not be selected automatically. Please select a local JDK installation, and then select the started process manually.`; const selectOption = 'Select JDK Installation'; vscode.window.showInformationMessage(msg, selectOption).then(selectedOption => { if (selectedOption === selectOption) { jdk.getPath(); } }); } } if (vmArgs.length) { if (!config.vmArgs) { config.vmArgs = vmArgs.join(' '); } else { if (Array.isArray(config.vmArgs)) { config.vmArgs.push(...vmArgs); } else { config.vmArgs = `${config.vmArgs} ${vmArgs.join(' ')}`; } } logUtils.logInfo(`[monitoredProcess] Added vmArgs for process startup: ${vmArgs.join(' ')}`); } else { logUtils.logInfo('[monitoredProcess] No vmArgs added for process startup'); } resolve(config); }); } } ================================================ FILE: integrations/vscode/src/nodes.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as visualvm from './visualvm'; import * as commands from './commands'; import * as parameters from './parameters'; import * as presets from './presets'; import * as runningProcesses from './runningProcesses'; import * as monitoredProcesses from './monitoredProcesses'; import * as logUtils from './logUtils'; const CONFIGURABLE_NODES_KEY = 'visualvm.configurableNodes'; const INVOKABLE_NODES_KEY = 'visualvm.invokableNodes'; export function initialize(context: vscode.ExtensionContext) { const configurableNodes = [ WhenStartedNode.CONTEXT_BASE + ConfigurableNode.CONFIGURABLE_SUFFIX, CpuSamplerFilterNode.CONTEXT_BASE + ConfigurableNode.CONFIGURABLE_SUFFIX, CpuSamplerSamplingRateNode.CONTEXT_BASE + ConfigurableNode.CONFIGURABLE_SUFFIX, MemorySamplerSamplingRateNode.CONTEXT_BASE + ConfigurableNode.CONFIGURABLE_SUFFIX, JfrSettingsNode.CONTEXT_BASE + ConfigurableNode.CONFIGURABLE_SUFFIX ]; vscode.commands.executeCommand('setContext', CONFIGURABLE_NODES_KEY, configurableNodes); const invokableNodes = [ ThreadDumpNode.CONTEXT_BASE + InvokableNode.INVOKABLE_SUFFIX, HeapDumpNode.CONTEXT_BASE + InvokableNode.INVOKABLE_SUFFIX, CpuSamplerNode.CONTEXT_BASE + InvokableNode.INVOKABLE_SUFFIX, MemorySamplerNode.CONTEXT_BASE + InvokableNode.INVOKABLE_SUFFIX, JfrNode.CONTEXT_BASE + InvokableNode.INVOKABLE_SUFFIX ]; vscode.commands.executeCommand('setContext', INVOKABLE_NODES_KEY, invokableNodes); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_SELECT_PROCESS_GLOBAL, async () => { const current = monitoredProcesses.getPids(); const selected = await runningProcesses.select(current); if (selected) { monitoredProcesses.add(selected); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_SELECT_PROCESS, async (node: ProcessNode) => { const current = monitoredProcesses.getPids(); const selected = await runningProcesses.select(current); if (selected) { monitoredProcesses.add(selected, node); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_CLEAR_PROCESS, (node: ProcessNode) => { const process = node.getProcess(); if (process) { monitoredProcesses.remove(process, node); } else { provider().removeProcessContainer(node); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_CONFIGURE_SETTING, (node: ConfigurableNode) => { node.configure(); })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_OPEN_PROCESS, async (node: BaseNode) => { const process = await findProcess(node); const pid = process?.getPid(); if (pid) { logUtils.logInfo(`[nodes] Opening process pid ${pid}`); visualvm.show(pid, process?.workspaceFolder); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_THREADDUMP_TAKE, async (node: BaseNode) => { const process = await findProcess(node); const pid = process?.getPid(); if (pid) { logUtils.logInfo(`[nodes] Taking thread dump for pid ${pid}`); const command = parameters.threadDump(pid); visualvm.perform(command, process?.workspaceFolder); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_HEAPDUMP_TAKE, async (node: BaseNode) => { const process = await findProcess(node); const pid = process?.getPid(); if (pid) { logUtils.logInfo(`[nodes] Taking heap dump for pid ${pid}`); const command = parameters.heapDump(pid); visualvm.perform(command, process?.workspaceFolder); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_CPU_SAMPLER_START, async (node: BaseNode) => { const processNode = findProcessNode(node); if (processNode) { const process = await findProcess(node); const pid = process?.getPid(); if (process && pid) { const samplingFilter = processNode.cpuSamplerFilterPresets.getSelectedValue(); const samplingRate = processNode.cpuSamplerSamplingRatePresets.getSelectedValue(); const workspaceFolder = process.workspaceFolder; logUtils.logInfo(`[nodes] Starting CPU sampling for pid ${pid} with filter ${samplingFilter} and sampling rate ${samplingRate} for folder ${workspaceFolder}`); const commandPromise = parameters.cpuSamplerStart(pid, samplingFilter, samplingRate, workspaceFolder); visualvm.perform(commandPromise, workspaceFolder); } } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_CPU_SAMPLER_SNAPSHOT, async (node: BaseNode) => { const process = await findProcess(node); const pid = process?.getPid(); if (pid) { logUtils.logInfo(`[nodes] Taking (CPU) sampling snapshot for pid ${pid}`); const command = parameters.samplerSnapshot(pid); visualvm.perform(command, process?.workspaceFolder); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_CPU_SAMPLER_STOP, async (node: BaseNode) => { const process = await findProcess(node); const pid = process?.getPid(); if (pid) { logUtils.logInfo(`[nodes] Stopping (CPU) sampling for pid ${pid}`); const command = parameters.samplerStop(pid); visualvm.perform(command, process?.workspaceFolder); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_MEMORY_SAMPLER_START, async (node: BaseNode) => { const processNode = findProcessNode(node); if (processNode) { const process = await findProcess(node); const pid = process?.getPid(); if (pid) { const samplingRate = processNode.memorySamplerSamplingRatePresets.getSelectedValue(); logUtils.logInfo(`[nodes] Starting memory sampling for pid ${pid} with sampling rate ${samplingRate}`); const command = parameters.memorySamplerStart(pid, samplingRate); visualvm.perform(command, process?.workspaceFolder); } } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_MEMORY_SAMPLER_SNAPSHOT, async (node: BaseNode) => { const process = await findProcess(node); const pid = process?.getPid(); if (pid) { logUtils.logInfo(`[nodes] Taking (memory) sampling snapshot for pid ${pid}`); const command = parameters.samplerSnapshot(pid); visualvm.perform(command, process?.workspaceFolder); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_MEMORY_SAMPLER_STOP, async (node: BaseNode) => { const process = await findProcess(node); const pid = process?.getPid(); if (pid) { logUtils.logInfo(`[nodes] Stopping (memory) sampling for pid ${pid}`); const command = parameters.samplerStop(pid); visualvm.perform(command, process?.workspaceFolder); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_JFR_START, async (node: BaseNode) => { const processNode = findProcessNode(node); if (processNode) { const process = await findProcess(processNode); const pid = process?.getPid(); if (process && pid) { const jfrSettings = processNode.jfrSettingsPresets.getSelectedValue(); logUtils.logInfo(`[nodes] Starting flight recording for pid ${pid} with settings ${jfrSettings}`); const command = parameters.jfrRecordingStart(pid, process.displayName, jfrSettings); visualvm.perform(command, process.workspaceFolder); } } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_JFR_DUMP, async (node: BaseNode) => { const process = await findProcess(node); const pid = process?.getPid(); if (pid) { logUtils.logInfo(`[nodes] Dumping flight recording data for pid ${pid}`); const command = parameters.jfrRecordingDump(pid); visualvm.perform(command, process?.workspaceFolder); } })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_JFR_STOP, async (node: BaseNode) => { const process = await findProcess(node); const pid = process?.getPid(); if (pid) { logUtils.logInfo(`[nodes] Stopping flight recording for pid ${pid}`); const command = parameters.jfrRecordingStop(pid); visualvm.perform(command, process?.workspaceFolder); } })); monitoredProcesses.onChanged((added, removed, target) => { provider().processesChanged(added, removed, target); }); context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(event => { if (event.affectsConfiguration(monitoredProcesses.AUTO_SELECT_PROJECT_PROCESS_KEY)) { const isAutoSelectProcess = vscode.workspace.getConfiguration().get(monitoredProcesses.AUTO_SELECT_PROJECT_PROCESS_KEY); logUtils.logInfo(`[nodes] Automatic process selection changed to ${isAutoSelectProcess ? 'enabled' : 'disabled'}`); provider().autoSelectProjectProcessChanged(!!isAutoSelectProcess); } })); } async function findProcess(node: BaseNode): Promise { const processNode = findProcessNode(node); if (processNode) { let process = processNode.getProcess(); if (!process) { const current = monitoredProcesses.getPids(); const selected = await runningProcesses.select(current); if (selected) { process = monitoredProcesses.add(selected, node); } } return process; } return undefined; } function findProcessNode(node: BaseNode): ProcessNode | undefined { while (node.parent !== undefined) { node = node.parent; } return node instanceof ProcessNode ? node as ProcessNode : undefined; } type TreeChanged = (node?: BaseNode) => void; class BaseNode extends vscode.TreeItem { parent: BaseNode | undefined; children: BaseNode[] | undefined | null; constructor(label: string, description: string | undefined, contextValue: string | undefined, children: BaseNode[] | undefined | null, expanded: boolean | undefined) { super(label); this.description = description; this.contextValue = contextValue; this.setChildren(children); if (!children || expanded === undefined) { this.collapsibleState = vscode.TreeItemCollapsibleState.None; } if (expanded === true) { this.collapsibleState = vscode.TreeItemCollapsibleState.Expanded; } else if (expanded === false) { this.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed; } } public setChildren(children: BaseNode[] | undefined | null) { if (this.children) { for (const child of this.children) { child.parent = undefined; } } this.children = children; if (this.children) { for (const child of this.children) { child.parent = this; } } } public getChildren(): BaseNode[] | undefined { return this.children ? this.children : undefined; } public removeFromParent(treeChanged?: TreeChanged): boolean { const parent = this.parent; if (parent) { this.parent = undefined; if (parent.removeChild(this)) { if (treeChanged) { treeChanged(parent); } return true; } } return false; } removeChild(child: BaseNode): boolean { if (this.children) { const idx = this.children.indexOf(child); if (idx >= 0) { this.children.splice(idx, 1); return true; } } return false; } } class ChangeableNode extends BaseNode { protected readonly treeChanged: TreeChanged; constructor(treeChanged: TreeChanged, label: string, description: string | undefined, contextValue: string | undefined, children: BaseNode[] | undefined | null, expanded: boolean | undefined) { super(label, description, contextValue, children, expanded); this.treeChanged = treeChanged; } } abstract class ConfigurableNode extends ChangeableNode { static readonly CONFIGURABLE_SUFFIX = '.configurable'; static readonly NOT_CONFIGURABLE_SUFFIX = 'notConfigurable'; private readonly contextBase: string; private readonly presets: presets.Presets; constructor(presets: presets.Presets, treeChanged: TreeChanged, label: string, description: string | undefined, contextBase: string, children: BaseNode[] | undefined | null, expanded: boolean | undefined) { super(treeChanged, label, description, `${contextBase}${ConfigurableNode.CONFIGURABLE_SUFFIX}`, children, expanded); this.contextBase = contextBase; this.presets = presets; this.presets.onChanged(() => { this.updateFromPresets(); this.treeChanged(this); }); this.updateFromPresets(); } setConfigurable(configurable: boolean) { // Only called from ProcessNode, tree will be refreshed from there this.contextValue = `${this.contextBase}${configurable ? ConfigurableNode.CONFIGURABLE_SUFFIX : ConfigurableNode.NOT_CONFIGURABLE_SUFFIX}`; } configure(actionName?: string) { actionName = actionName || `Configure ${this.presets.name}`; this.presets.select(actionName); } protected getPresetValue(): string { return this.presets.getSelectedValue(); } private updateFromPresets() { this.description = this.presets.getSelectedString(); } } abstract class InvokableNode extends BaseNode { static readonly INVOKABLE_SUFFIX = '.invokable'; static readonly NOT_INVOKABLE_SUFFIX = '.notInvokable'; private readonly contextBase: string; constructor(label: string, description: string | undefined, contextBase: string, children: BaseNode[] | undefined | null, expanded: boolean | undefined) { super(label, description, `${contextBase}${InvokableNode.INVOKABLE_SUFFIX}`, children, expanded); this.contextBase = contextBase; } setInvokable(invokable: boolean) { // Only called from ProcessNode, tree will be refreshed from there this.contextValue = `${this.contextBase}${invokable ? InvokableNode.INVOKABLE_SUFFIX : InvokableNode.NOT_INVOKABLE_SUFFIX}`; } } class WhenStartedNode extends ConfigurableNode { static readonly CONTEXT_BASE = 'visualvm.WhenStartedNode'; constructor(presets: presets.Presets, treeChanged: TreeChanged) { super(presets, treeChanged, 'When started:', undefined, WhenStartedNode.CONTEXT_BASE, undefined, undefined); this.tooltip = 'Action when a project process is started'; } } class ThreadDumpNode extends InvokableNode { static readonly CONTEXT_BASE = 'visualvm.ThreadDumpNode'; constructor() { super('Thread dump', undefined, ThreadDumpNode.CONTEXT_BASE, undefined, undefined); this.tooltip = 'Take a thread dump and open it in VisualVM'; } } class HeapDumpNode extends InvokableNode { static readonly CONTEXT_BASE = 'visualvm.HeapDumpNode'; constructor() { super('Heap dump', undefined, HeapDumpNode.CONTEXT_BASE, undefined, undefined); this.tooltip = 'Take a heap dump and open it in VisualVM'; } } class CpuSamplerNode extends InvokableNode { static readonly CONTEXT_BASE = 'visualvm.CpuSamplerNode'; constructor(presets: presets.Presets[], treeChanged: TreeChanged) { super('CPU sampler', undefined, CpuSamplerNode.CONTEXT_BASE, [ ...CpuSamplerNode.createNodes(presets, treeChanged) ], false); this.tooltip = 'Control a CPU sampling session in VisualVM'; } private static createNodes(presets: presets.Presets[], treeChanged: TreeChanged): BaseNode[] { const nodes: BaseNode[] = []; nodes.push(new CpuSamplerFilterNode(presets[0], treeChanged)); nodes.push(new CpuSamplerSamplingRateNode(presets[1], treeChanged)); return nodes; } } class CpuSamplerFilterNode extends ConfigurableNode { static readonly CONTEXT_BASE = 'visualvm.CpuSamplerFilterNode'; constructor(presets: presets.Presets, treeChanged: TreeChanged) { super(presets, treeChanged, 'Filter:', undefined, CpuSamplerFilterNode.CONTEXT_BASE, undefined, undefined); this.tooltip = 'CPU sampling filter'; } } class CpuSamplerSamplingRateNode extends ConfigurableNode { static readonly CONTEXT_BASE = 'visualvm.CpuSamplerSamplingRateNode'; constructor(presets: presets.Presets, treeChanged: TreeChanged) { super(presets, treeChanged, 'Sampling rate:', undefined, CpuSamplerSamplingRateNode.CONTEXT_BASE, undefined, undefined); this.tooltip = 'CPU sampling rate'; } } class MemorySamplerNode extends InvokableNode { static readonly CONTEXT_BASE = 'visualvm.MemorySamplerNode'; constructor(presets: presets.Presets, treeChanged: TreeChanged) { super('Memory sampler', undefined, MemorySamplerNode.CONTEXT_BASE, [ ...MemorySamplerNode.createNodes(presets, treeChanged) ], false); this.tooltip = 'Control a memory sampling session in VisualVM'; } private static createNodes(presets: presets.Presets, treeChanged: TreeChanged): BaseNode[] { const nodes: BaseNode[] = []; nodes.push(new MemorySamplerSamplingRateNode(presets, treeChanged)); return nodes; } } class MemorySamplerSamplingRateNode extends ConfigurableNode { static readonly CONTEXT_BASE = 'visualvm.MemorySamplerSamplingRateNode'; constructor(presets: presets.Presets, treeChanged: TreeChanged) { super(presets, treeChanged, 'Sampling rate:', undefined, MemorySamplerSamplingRateNode.CONTEXT_BASE, undefined, undefined); this.tooltip = 'Memory sampling rate'; } } class JfrNode extends InvokableNode { static readonly CONTEXT_BASE = 'visualvm.JfrNode'; constructor(presets: presets.Presets, treeChanged: TreeChanged) { super('JFR', undefined, JfrNode.CONTEXT_BASE, [ ...JfrNode.createNodes(presets, treeChanged) ], false); this.tooltip = 'Control a flight recording session in VisualVM'; } private static createNodes(presets: presets.Presets, treeChanged: TreeChanged): BaseNode[] { const nodes: BaseNode[] = []; nodes.push(new JfrSettingsNode(presets, treeChanged)); return nodes; } } class JfrSettingsNode extends ConfigurableNode { static readonly CONTEXT_BASE = 'visualvm.JfrSettingsNode'; constructor(presets: presets.Presets, treeChanged: TreeChanged) { super(presets, treeChanged, 'Settings:', undefined, JfrSettingsNode.CONTEXT_BASE, undefined, undefined); this.tooltip = 'Flight recorder settings'; } } class ProcessNode extends ChangeableNode { private static CONTEXT_BASE = 'visualvm.ProcessNode'; private static CONTEXT_NO_PROCESS = `${this.CONTEXT_BASE}.noProcess`; private static CONTEXT_HAS_ID = `${this.CONTEXT_BASE}.hasId`; private static CONTEXT_HAS_PID = `${this.CONTEXT_BASE}.hasPid`; // private static CONTEXT_TERMINATED = `${this.CONTEXT_BASE}.terminated`; readonly isMaster: boolean; private isAutoSelectProcess: boolean; readonly whenStartedPresets: presets.Presets; readonly cpuSamplerFilterPresets: presets.Presets; readonly cpuSamplerSamplingRatePresets: presets.Presets; readonly memorySamplerSamplingRatePresets: presets.Presets; readonly jfrSettingsPresets: presets.Presets; private process: monitoredProcesses.MonitoredProcess | undefined; // process: undefined -> isMaster, null -> isMaster && persistentPresets constructor(treeChanged: TreeChanged, process?: monitoredProcesses.MonitoredProcess | undefined | null, isAutoSelectProcess?: boolean) { super(treeChanged, 'Process:', undefined, ProcessNode.CONTEXT_NO_PROCESS, [], !process); this.tooltip = 'Java process monitored by VisualVM'; this.isMaster = !process; this.isAutoSelectProcess = !!isAutoSelectProcess; const persistentPresets = process === null; this.whenStartedPresets = persistentPresets ? presets.WhenStartedPresets.PERSISTENT : new presets.WhenStartedPresets(); this.cpuSamplerFilterPresets = persistentPresets ? presets.CpuSamplerFilterPresets.PERSISTENT : new presets.CpuSamplerFilterPresets(); this.cpuSamplerSamplingRatePresets = persistentPresets ? presets.CpuSamplerSamplingRatePresets.PERSISTENT : new presets.CpuSamplerSamplingRatePresets(); this.memorySamplerSamplingRatePresets = persistentPresets ? presets.MemorySamplerSamplingRatePresets.PERSISTENT : new presets.MemorySamplerSamplingRatePresets(); this.jfrSettingsPresets = persistentPresets ? presets.JfrSettingsPresets.PERSISTENT : new presets.JfrSettingsPresets(); const nodes: BaseNode[] = []; nodes.push(new ThreadDumpNode()); nodes.push(new HeapDumpNode()); nodes.push(new CpuSamplerNode([ this.cpuSamplerFilterPresets, this.cpuSamplerSamplingRatePresets ], treeChanged)); nodes.push(new MemorySamplerNode(this.memorySamplerSamplingRatePresets, treeChanged)); nodes.push(new JfrNode(this.jfrSettingsPresets, treeChanged)); this.setChildren(nodes); this.setProcess(process ? process : undefined); } getProcess(): monitoredProcesses.MonitoredProcess | undefined { return this.process; } setProcess(process: monitoredProcesses.MonitoredProcess | undefined) { this.process = process; this.process?.onPidChanged(() => { this.updateProcess(); }); this.updateProcess(true); this.updateWhenStartedAvailable(); } autoSelectProcessChanged(isAutoSelectProcess: boolean) { this.isAutoSelectProcess = isAutoSelectProcess; if (!this.process) { this.description = this.descriptionHint(); this.treeChanged(this); } this.updateWhenStartedAvailable(); } private updateWhenStartedAvailable(): boolean { if (this.isMaster) { const hasWhenStartedNode = !!this.whenStartedNode(); const hasSupportedProcess = this.process === undefined || !this.process.isManuallySelected; if (this.isAutoSelectProcess && hasSupportedProcess) { if (!hasWhenStartedNode) { const whenStartedNode = new WhenStartedNode(this.whenStartedPresets, this.treeChanged); whenStartedNode.parent = this; this.children?.unshift(whenStartedNode); this.treeChanged(this); return true; } } else { if (hasWhenStartedNode) { this.children?.splice(0, 1); this.treeChanged(this); return true; } } } return false; } private updateProcess(initialUpdate: boolean = false) { if (this.process) { const name = this.process.displayName; const pid = this.process.getPid(); if (pid === null) { // Do not update & refresh, will be reset/removed immediately after return; // this.description = `${name} (terminated)`; // this.contextValue = ProcessNode.CONTEXT_TERMINATED; } else if (pid === undefined) { this.description = `${name} (pid pending...)`; this.contextValue = ProcessNode.CONTEXT_HAS_ID; this.updateInvokables(false); } else { this.description = `${name} (pid ${pid})`; this.contextValue = ProcessNode.CONTEXT_HAS_PID; if (!initialUpdate) { setTimeout(() => { this.handleWhenStarted(); }, 0); } this.updateInvokables(true); } this.whenStartedNode()?.setConfigurable(false); } else { this.description = this.descriptionHint(); this.contextValue = ProcessNode.CONTEXT_NO_PROCESS; this.whenStartedNode()?.setConfigurable(true); this.updateInvokables(true); } this.treeChanged(this); } private descriptionHint(): string { return this.isAutoSelectProcess ? 'start new or select running...' : 'select running...'; } private whenStartedNode(): WhenStartedNode | undefined { return this.children?.[0] instanceof WhenStartedNode ? (this.children[0] as WhenStartedNode) : undefined; } private handleWhenStarted() { const whenStartedNode = this.whenStartedNode(); if (whenStartedNode) { // When started is supported const command = this.whenStartedPresets.getSelectedValue(); if (command) { // When started is set up to perform an action vscode.commands.executeCommand(command, whenStartedNode); } } } private updateInvokables(invokable: boolean) { if (this.children) { for (const child of this.children) { if (child instanceof InvokableNode) { (child as InvokableNode).setInvokable(invokable); } } } } } class Provider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; private readonly treeChanged: TreeChanged = (node?: BaseNode) => { if (this.visible) { if (node) { const processNode = findProcessNode(node); if (!processNode || !this.roots.includes(processNode)) { // node already removed from tree return; } } this.refresh(node); } }; private readonly roots: ProcessNode[] = [ new ProcessNode(this.treeChanged, null, vscode.workspace.getConfiguration().get(monitoredProcesses.AUTO_SELECT_PROJECT_PROCESS_KEY)) ]; private visible: boolean = false; processesChanged(added: monitoredProcesses.MonitoredProcess | undefined, removed: monitoredProcesses.MonitoredProcess | undefined, target: any | undefined) { if (removed) { for (let index = 0; index < this.roots.length; index++) { const root = this.roots[index]; if (root.getProcess() === removed) { if (root.isMaster) { root.setProcess(undefined); this.refresh(root); } else { this.roots.splice(index, 1); this.refresh(); } break; } } } else if (added) { const targetNode = target instanceof ProcessNode ? target as ProcessNode : undefined; let processRoot: ProcessNode | undefined = targetNode; if (!processRoot) { for (const root of this.roots) { if (root.getProcess() === undefined) { processRoot = root; break; } } } if (processRoot) { processRoot.setProcess(added); this.refresh(processRoot); } else { processRoot = new ProcessNode(this.treeChanged, added); this.roots.push(processRoot); this.refresh(); } } } autoSelectProjectProcessChanged(isAutoSelectProcess: boolean) { for (const root of this.roots) { if (root.isMaster) { root.autoSelectProcessChanged(isAutoSelectProcess); } } } removeProcessContainer(root: ProcessNode) { const index = this.roots.indexOf(root); if (index > -1) { this.roots.splice(index, 1); this.refresh(); } } refresh(element?: vscode.TreeItem) { this._onDidChangeTreeData.fire(element); } getTreeItem(element: vscode.TreeItem): vscode.TreeItem { return element; } getChildren(element?: vscode.TreeItem): vscode.TreeItem[] { if (!this.visible) { return []; } else if (!element) { return this.roots; } else { return (element as BaseNode).getChildren() || []; } } getParent?(element: vscode.TreeItem): vscode.TreeItem | undefined { return (element as BaseNode).parent; } setVisible(visible: boolean) { if (this.visible !== visible) { this.visible = visible; this.refresh(); } } } let PROVIDER: Provider | undefined; export function provider(): Provider { PROVIDER = PROVIDER || new Provider(); return PROVIDER; } ================================================ FILE: integrations/vscode/src/parameters.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as fs from 'fs'; import * as os from 'os'; import * as path from 'path'; import * as jdk from './jdk'; import * as projectUtils from './projectUtils'; import * as vscodeUtils from './vscodeUtils'; // import * as logUtils from './logUtils'; export const CPU_SAMPLER_FILTER_INCLUSIVE = 'include-classes'; export const CPU_SAMPLER_FILTER_EXCLUSIVE = 'exclude-classes'; const ENABLE_GO_TO_SOURCE_KEY = 'visualvm.integration.enableGoToSource'; const VSCODE_PARAMETERS_KEY = 'visualvm.integration.visualStudioCodeParameters'; const USE_JDK_PATH_FOR_STARTUP_KEY = 'visualvm.startup.useJdkPathForVisualvm'; const STARTUP_PARAMETERS_KEY = 'visualvm.startup.visualvmParameters'; const WINDOW_TO_FRONT_KEY = 'visualvm.behavior.visualvmWindowToFront'; const PRESELECT_VIEW_KEY = 'visualvm.behavior.preselectProcessView'; export function executable(executable: string): string { return executable.includes(' ') ? `"${executable}"` : executable; } export function perfMaxStringConstLength(): string { return '-J-XX:PerfMaxStringConstLength=10240'; } export async function jdkHome(predefinedJdk?: string): Promise { if (vscode.workspace.getConfiguration().get(USE_JDK_PATH_FOR_STARTUP_KEY)) { const jdkPath = predefinedJdk || await jdk.getPath(); if (!jdkPath) { throw new Error(); } return `--jdkhome "${jdkPath}"`; } return undefined; } export function windowToFront(): string { return '--window-to-front'; } export function windowToFrontConditional(): string | undefined { if (vscode.workspace.getConfiguration().get(WINDOW_TO_FRONT_KEY)) { return windowToFront(); } return undefined; } export function userDefinedParameters(): string | undefined { return vscode.workspace.getConfiguration().get(STARTUP_PARAMETERS_KEY); } export async function goToSource(folder?: vscode.WorkspaceFolder): Promise { const parameters: string[] = []; if (vscode.workspace.getConfiguration().get(ENABLE_GO_TO_SOURCE_KEY)) { const vsCodeLauncher = vscodeUtils.findLauncher(); const vsCodeLauncherParameters = vscode.workspace.getConfiguration().get(VSCODE_PARAMETERS_KEY, ''); const vsCodeLauncherCommand = vsCodeLauncher ? `${vsCodeLauncher}${vsCodeLauncherParameters ? ' ' + vsCodeLauncherParameters : ''}` : ''; const sourceViewer = vsCodeLauncher ? `${encode(vsCodeLauncherCommand)} -g {file}:{line}:{column}` : ''; const sourceRootsArr: string[] = []; const workspaceSourceRoots = await getWorkspaceSourceRoots(folder); if (workspaceSourceRoots) { sourceRootsArr.push(...workspaceSourceRoots); } const jdkSourceRoots = await getJdkSourceRoots(); if (jdkSourceRoots) { sourceRootsArr.push(jdkSourceRoots); } const sourceRoots = sourceRootsArr.length ? sourceRootsArr.join(path.delimiter) : ''; if (sourceViewer.length + sourceRoots.length < 200) { parameters.push(`--source-viewer="${sourceViewer}"`); parameters.push(`--source-roots="${sourceRoots}"`); } else { const file = await writeProperties('visualvm-source-config', `source-viewer=${sourceViewer}`, `source-roots=${sourceRoots}`); if (file) { parameters.push(`--source-config="${encode(file)}"`); } } } else { // Make sure to reset the previously forced settings parameters.push('--source-viewer=""'); parameters.push('--source-roots=""'); } return parameters.length ? parameters.join(' ') : undefined; } export async function getWorkspaceSourceRoots(folder?: vscode.WorkspaceFolder): Promise { const sourceRoots = await projectUtils.getSourceRoots(folder); if (sourceRoots) { for (let index = 0; index < sourceRoots.length; index++) { sourceRoots[index] = encode(sourceRoots[index]); } } return sourceRoots; } export async function getJdkSourceRoots(): Promise { const jdkPath = await jdk.getPath(); if (jdkPath) { const jdkSources = await jdk.getSources(jdkPath); if (jdkSources) { const jdkSourcesPath = fs.realpathSync(jdkSources.path); // JDK sources may be a symbolic link on linux return `${encode(jdkSourcesPath)}${jdkSources.modular ? '[subpaths=*modules*]' : ''}`; } } return undefined; } export function openPid(pid: number): string { const view = vscode.workspace.getConfiguration().get(PRESELECT_VIEW_KEY); function viewIndex(view: string | undefined): number { switch (view) { case 'Overview': return 1; case 'Monitor': return 2; case 'Threads': return 3; case 'Sampler': return 4; default: return 0; } } const index = viewIndex(view); const param = index ? `${pid}@${index}` : `${pid}`; return `--openpid ${param}`; } export function threadDump(pid: number): string { return `--threaddump ${pid.toString()}`; } export function heapDump(pid: number): string { return `--heapdump ${pid.toString()}`; } export async function cpuSamplerStart(pid: number, samplingFilter?: string, samplingRate?: number | string, workspaceFolder?: vscode.WorkspaceFolder): Promise { const samplingFilterP = await resolveSamplingFilter(samplingFilter, workspaceFolder); if (samplingFilterP !== undefined) { if (typeof samplingRate !== 'string') { samplingRate = Number(samplingRate || 100).toString(); } const parameters: string[] = []; parameters.push(`--start-cpu-sampler ${pid}`); const samplingRateP = `sampling-rate=${samplingRate}`; if (samplingFilterP.length + samplingRateP.length < 200) { parameters.push('@'); parameters.push(samplingFilterP); parameters.push(','); parameters.push(samplingRateP); } else { const file = await writeProperties('visualvm-sampler-config', samplingFilterP, samplingRateP); if (file) { parameters.push(`@settings-file="${encode(file)}"`); } } return parameters.join(''); } else { return undefined; } } export async function resolveSamplingFilter(samplingFilter?: string, workspaceFolder?: vscode.WorkspaceFolder): Promise { switch (samplingFilter) { case CPU_SAMPLER_FILTER_EXCLUSIVE: // exclude JDK classes const jdkPackages = jdk.getPackages(); return `${CPU_SAMPLER_FILTER_EXCLUSIVE}=${encode(jdkPackages)}`; case CPU_SAMPLER_FILTER_INCLUSIVE: // include only project classes const projectPackages = await projectUtils.getPackages(workspaceFolder); if (projectPackages?.length) { const packages = projectPackages.join(', '); return `${CPU_SAMPLER_FILTER_INCLUSIVE}=${encode(packages)}`; } else { const reason = projectPackages === undefined ? 'No Java support available to resolve project classes' : 'No project classes found'; const msg = `${reason}. Select how to proceed:`; const allOption = 'Include All Classes'; const jdkOption = 'Exclude JDK Classes'; const cancelOption = 'Cancel CPU Sampler'; const selected = await vscode.window.showWarningMessage(msg, allOption, jdkOption, cancelOption); if (selected === allOption) { return resolveSamplingFilter(); } else if (selected === jdkOption) { return resolveSamplingFilter(CPU_SAMPLER_FILTER_EXCLUSIVE); } else { return undefined; } } default: if (samplingFilter?.startsWith(CPU_SAMPLER_FILTER_EXCLUSIVE + ':')) { // exclude custom classes const filter = samplingFilter.substring(CPU_SAMPLER_FILTER_EXCLUSIVE.length + 1); return `${CPU_SAMPLER_FILTER_EXCLUSIVE}=${encode(filter)}`; } else { // include custom or all classes const filter = samplingFilter?.startsWith(CPU_SAMPLER_FILTER_INCLUSIVE + ':') ? samplingFilter.substring(CPU_SAMPLER_FILTER_INCLUSIVE.length + 1) : ''; return `${CPU_SAMPLER_FILTER_INCLUSIVE}=${encode(filter)}`; } } } export function memorySamplerStart(pid: number, samplingRate?: number | string): string { if (typeof samplingRate !== 'string') { samplingRate = Number(samplingRate || 1000).toString(); } const parameters: string[] = []; parameters.push(`--start-memory-sampler ${pid}`); parameters.push('@'); parameters.push(`sampling-rate=${samplingRate}`); return parameters.join(''); } export function samplerSnapshot(pid: number): string { return `--snapshot-sampler ${pid}`; } export function samplerStop(pid: number): string { return `--stop-sampler ${pid}`; } export function jfrRecordingStart(pid: number, displayName: string, settingsName?: string): string { const parameters: string[] = []; parameters.push(`--start-jfr ${pid}`); parameters.push('@'); parameters.push(`name=${encode(displayName)}`); parameters.push(','); parameters.push(`settings=${settingsName || 'default'}`); return parameters.join(''); } export function jfrRecordingDump(pid: number) { return `--dump-jfr ${pid}`; } export function jfrRecordingStop(pid: number) { return `--stop-jfr ${pid}`; } export function vmArgId(id: string): string { return `-Dvisualvm.id=${id}`; } export function vmArgDisplayName(displayName: string, includePid: boolean = true): string { displayName = displayName.replace(/\s/g, '_'); return `-Dvisualvm.display.name=${displayName}${includePid ? '%PID' : ''}`; } export function encode(text: string | undefined): string { if (text === undefined) return 'undefined'; if (text.length) { text = text.replace(/\'/g, '%27'); text = text.replace(/\"/g, '%22'); text = text.replace(/\s/g, '%20'); text = text.replace( /,/g, '%2C'); } return text; } async function writeProperties(filename: string, ...records: string[]): Promise { return new Promise( (resolve) => { const tmp = getTmpDir(); if (tmp) { const file = path.join(tmp, filename); const stream = fs.createWriteStream(path.join(tmp, filename), { flags: 'w', encoding: 'utf8' }); for (let record of records) { stream.write(record.replace(/\\/g, '\\\\') + '\n'); } stream.on('finish', () => { resolve(file); }); stream.end(); } else { resolve(undefined); } } ); } export function getTmpDir(): string { const tmp = os.tmpdir(); const realtmp = fs.realpathSync(tmp); return realtmp; } ================================================ FILE: integrations/vscode/src/presets.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as commands from './commands'; import * as parameters from './parameters'; export function initialize(context: vscode.ExtensionContext) { WhenStartedPresets.PERSISTENT.initializePersistent(context); CpuSamplerFilterPresets.PERSISTENT.initializePersistent(context); CpuSamplerSamplingRatePresets.PERSISTENT.initializePersistent(context); MemorySamplerSamplingRatePresets.PERSISTENT.initializePersistent(context); JfrSettingsPresets.PERSISTENT.initializePersistent(context); } export type OnChanged = () => void; export abstract class Presets { readonly name: string; private readonly presets: string[][]; private selectedPreset: number; private readonly selectPrompt: string; private readonly singleRowChoices: boolean; private storage: vscode.Memento | undefined; private persistenceKey: string | undefined; protected constructor(name: string, presets: string[][], initialPreset: number, selectPrompt: string, singleRowChoices: boolean) { this.name = name; this.presets = presets; this.selectedPreset = initialPreset; this.selectPrompt = selectPrompt; this.singleRowChoices = singleRowChoices; } protected doInitializePersistent(storage: vscode.Memento, persistenceKey: string) { this.storage = storage; this.persistenceKey = persistenceKey; const loadedPreset = this.storage.get(persistenceKey, this.selectedPreset); if (loadedPreset !== this.selectedPreset) { this.selectedPreset = loadedPreset; this.notifyChanged(); } } async select(actionName?: string): Promise { const choices: (vscode.QuickPickItem & { index: number })[] = []; for (let index = 0; index < this.presets.length; index++) { choices.push({ label: this.presets[index][0], description: this.singleRowChoices ? this.presets[index][1] : undefined, detail: this.singleRowChoices ? undefined : this.presets[index][1], index: index }); } const selected = await vscode.window.showQuickPick(choices, { title: actionName, placeHolder: this.selectPrompt }); if (selected) { return this.setSelected(selected.index); } else { return undefined; } } getSelectedString(): string { return this.presets[this.selectedPreset][0].toLocaleLowerCase(); } getSelectedValue(): string { return this.presets[this.selectedPreset][2]; } protected getSelectedPreset(): number { return this.selectedPreset; } protected async setSelected(preset: number, forceSelected: boolean = false): Promise { if (forceSelected || this.selectedPreset !== preset) { this.selectedPreset = preset; await this.savePersistent(this.persistenceKey, this.selectedPreset); this.notifyChanged(); return true; } else { return false; } } protected async savePersistent(key: string | undefined, value: any): Promise { if (this.storage && key) { await this.storage.update(key, value); } } private readonly listeners: OnChanged[] = []; onChanged(listener: OnChanged) { this.listeners.push(listener); } private notifyChanged() { for (const listener of this.listeners) { listener(); } } } export class WhenStartedPresets extends Presets { private static PERSISTENCE_KEY = 'visualvm.presets.WhenStarted'; private static NAME = 'When Started Action'; private static SELECT_PROMPT = 'Select what happens when a project process is started'; private static PRESETS = [ [ 'Do Nothing', 'No action when process is started', '' ], [ 'Open Process', 'Open the process in VisualVM', commands.COMMAND_OPEN_PROCESS ], [ 'Start CPU Sampler', 'Open the process in VisualVM and start CPU sampling using the defined settings', commands.COMMAND_CPU_SAMPLER_START ], [ 'Start Memory Sampler', 'Open the process in VisualVM and start memory sampling using the defined settings', commands.COMMAND_MEMORY_SAMPLER_START ], [ 'Start JFR Recording', 'Open the process in VisualVM and start flight recording using the defined settings', commands.COMMAND_JFR_START ] ]; private static INITIAL_PRESET = 0; private static SINGLE_ROW_CHOICES = false; static PERSISTENT = new WhenStartedPresets(); constructor() { super(WhenStartedPresets.NAME, WhenStartedPresets.PRESETS, WhenStartedPresets.INITIAL_PRESET, WhenStartedPresets.SELECT_PROMPT, WhenStartedPresets.SINGLE_ROW_CHOICES); } initializePersistent(context: vscode.ExtensionContext) { this.doInitializePersistent(context.workspaceState, WhenStartedPresets.PERSISTENCE_KEY); } getSelectedString(): string { return super.getSelectedString().replace(/ cpu /g, ' CPU ').replace(/ memory /g, ' Memory ').replace(/ jfr /g, ' JFR '); } } export class CpuSamplerFilterPresets extends Presets { private static PERSISTENCE_KEY = 'visualvm.presets.CpuSamplerFilter'; private static PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_INCLUSIVE = 'visualvm.presets.CpuSamplerFilterCustomInclusive'; private static PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_EXCLUSIVE = 'visualvm.presets.CpuSamplerFilterCustomExclusive'; private static NAME = 'CPU Sampling Filter'; private static SELECT_PROMPT = 'Select CPU sampling filter'; private static PRESETS = [ [ 'Include All Classes', 'Collects data from all classes', '' ], [ 'Exclude JDK Classes', 'Excludes data from JDK classes (java.*, com.sun.*, org.graalvm.*, etc.)', parameters.CPU_SAMPLER_FILTER_EXCLUSIVE ], [ 'Include Only Project Classes', 'Collects data only from project classes', parameters.CPU_SAMPLER_FILTER_INCLUSIVE ], [ 'Include Only Defined Classes', 'Collects data only from user defined classes', parameters.CPU_SAMPLER_FILTER_INCLUSIVE ], [ 'Exclude Defined Classes', 'Excludes data from user defined classes', parameters.CPU_SAMPLER_FILTER_EXCLUSIVE ] ]; private static INITIAL_PRESET = 0; private static SINGLE_ROW_CHOICES = false; static PERSISTENT = new CpuSamplerFilterPresets(); private customInclusiveFilter: string = '*'; private customExclusiveFilter: string = '*'; constructor() { super(CpuSamplerFilterPresets.NAME, CpuSamplerFilterPresets.PRESETS, CpuSamplerFilterPresets.INITIAL_PRESET, CpuSamplerFilterPresets.SELECT_PROMPT, CpuSamplerFilterPresets.SINGLE_ROW_CHOICES); } initializePersistent(context: vscode.ExtensionContext) { this.doInitializePersistent(context.workspaceState, CpuSamplerFilterPresets.PERSISTENCE_KEY); this.customInclusiveFilter = context.workspaceState.get(CpuSamplerFilterPresets.PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_INCLUSIVE, '*'); this.customExclusiveFilter = context.workspaceState.get(CpuSamplerFilterPresets.PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_EXCLUSIVE, '*'); } protected async setSelected(preset: number): Promise { if (preset >= 3) { function validateFilter(filter: string): string | undefined { if (!filter.length) { return 'Filter cannot be empty'; } // TODO: validate properly return undefined; } const newValue = await vscode.window.showInputBox({ title: CpuSamplerFilterPresets.PRESETS[preset][0], value: preset === 3 ? this.customInclusiveFilter : this.customExclusiveFilter, placeHolder: 'Define CPU sampling filter', prompt: 'Format: org.pkg.**, org.pkg.*, org.pkg.Class', validateInput: filter => validateFilter(filter) }); if (newValue) { if (preset === 3) { this.customInclusiveFilter = newValue.trim(); await this.savePersistent(CpuSamplerFilterPresets.PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_INCLUSIVE, this.customInclusiveFilter); } else if (preset === 4) { this.customExclusiveFilter = newValue.trim(); await this.savePersistent(CpuSamplerFilterPresets.PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_EXCLUSIVE, this.customExclusiveFilter); } return super.setSelected(preset, true); } else { return undefined; } } else { return super.setSelected(preset); } } getSelectedString(): string { switch (this.getSelectedPreset()) { case 3: return `include ${this.customInclusiveFilter}`; case 4: return `exclude ${this.customExclusiveFilter}`; default: return super.getSelectedString().replace(/ jdk /g, ' JDK '); } } getSelectedValue(): string { switch (this.getSelectedPreset()) { case 3: return `${parameters.CPU_SAMPLER_FILTER_INCLUSIVE}:${this.customInclusiveFilter}`; case 4: return `${parameters.CPU_SAMPLER_FILTER_EXCLUSIVE}:${this.customExclusiveFilter}`; default: return super.getSelectedValue(); } } } export class CpuSamplerSamplingRatePresets extends Presets { private static PERSISTENCE_KEY = 'visualvm.presets.CpuSamplerSamplingRate'; private static NAME = 'CPU Sampling Rate'; private static SELECT_PROMPT = 'Select CPU sampling rate'; private static SAMPLING_RATES = [ 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]; private static PRESETS: string[][] = []; static { for (const samplingRate of this.SAMPLING_RATES) { this.PRESETS.push([ Number(samplingRate).toLocaleString(), 'ms', Number(samplingRate).toString() ]); } } private static INITIAL_PRESET = 2; private static SINGLE_ROW_CHOICES = true; static PERSISTENT = new CpuSamplerSamplingRatePresets(); constructor() { super(CpuSamplerSamplingRatePresets.NAME, CpuSamplerSamplingRatePresets.PRESETS, CpuSamplerSamplingRatePresets.INITIAL_PRESET, CpuSamplerSamplingRatePresets.SELECT_PROMPT, CpuSamplerSamplingRatePresets.SINGLE_ROW_CHOICES); } initializePersistent(context: vscode.ExtensionContext) { this.doInitializePersistent(context.workspaceState, CpuSamplerSamplingRatePresets.PERSISTENCE_KEY); } getSelectedString(): string { return `${super.getSelectedString()} ms`; } } export class MemorySamplerSamplingRatePresets extends Presets { private static PERSISTENCE_KEY = 'visualvm.presets.MemorySamplerSamplingRate'; private static NAME = 'Memory Sampling Rate'; private static SELECT_PROMPT = 'Select memory sampling rate'; private static SAMPLING_RATES = [ 100, 200, 500, 1000, 2000, 5000, 10000]; private static PRESETS: string[][] = []; static { for (const samplingRate of this.SAMPLING_RATES) { this.PRESETS.push([ Number(samplingRate).toLocaleString(), 'ms', Number(samplingRate).toString() ]); } } private static INITIAL_PRESET = 3; private static SINGLE_ROW_CHOICES = true; static PERSISTENT = new MemorySamplerSamplingRatePresets(); constructor() { super(MemorySamplerSamplingRatePresets.NAME, MemorySamplerSamplingRatePresets.PRESETS, MemorySamplerSamplingRatePresets.INITIAL_PRESET, MemorySamplerSamplingRatePresets.SELECT_PROMPT, MemorySamplerSamplingRatePresets.SINGLE_ROW_CHOICES); } initializePersistent(context: vscode.ExtensionContext) { this.doInitializePersistent(context.workspaceState, MemorySamplerSamplingRatePresets.PERSISTENCE_KEY); } getSelectedString(): string { return `${super.getSelectedString()} ms`; } } export class JfrSettingsPresets extends Presets { private static PERSISTENCE_KEY = 'visualvm.presets.JfrSettings'; private static NAME = 'Flight Recording Settings'; private static SELECT_PROMPT = 'Select JFR settings'; private static PRESETS = [ [ 'Default', 'Collects a predefined set of information with low overhead', 'default' ], [ 'Profile', 'Provides more data than the Default setting, but with more overhead and impact on performance', 'profile' ] ]; private static INITIAL_PRESET = 0; private static SINGLE_ROW_CHOICES = false; static PERSISTENT = new JfrSettingsPresets(); constructor() { super(JfrSettingsPresets.NAME, JfrSettingsPresets.PRESETS, JfrSettingsPresets.INITIAL_PRESET, JfrSettingsPresets.SELECT_PROMPT, JfrSettingsPresets.SINGLE_ROW_CHOICES); } initializePersistent(context: vscode.ExtensionContext) { this.doInitializePersistent(context.workspaceState, JfrSettingsPresets.PERSISTENCE_KEY); } } ================================================ FILE: integrations/vscode/src/projectUtils.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as path from 'path'; import * as fs from 'fs'; import * as logUtils from './logUtils'; const NBLS_GET_SOURCE_ROOTS_COMMAND = 'nbls.java.get.project.source.roots'; const NBLS_GET_PACKAGES_COMMAND = 'nbls.java.get.project.packages'; const NBLS_PROJECT_INFO_COMMAND = 'nbls.project.info'; const JDT_EXTENSION_ID = 'redhat.java'; const JDT_SETTINGS_SOURCE_PATHS = 'org.eclipse.jdt.ls.core.sourcePaths'; const JDT_GET_PACKAGE_DATA = 'java.getPackageData'; const JDT_EXECUTE_WORKSPACE_COMMAND = 'java.execute.workspaceCommand'; const MICRONAUT_TOOLS_SELECTED_SUBPROJECT_COMMAND = 'extension.micronaut-tools.navigation.getSelectedSubproject'; export async function getSourceRoots(workspaceFolder?: vscode.WorkspaceFolder): Promise { logUtils.logInfo(`[projectUtils] Computing source roots${workspaceFolder ? ' for folder ' + workspaceFolder.uri.fsPath : ''}...`); if (!vscode.workspace.workspaceFolders?.length) { // No folder opened logUtils.logInfo('[projectUtils] No folder opened'); return []; } const workspaceFolders = []; for (const folder of vscode.workspace.workspaceFolders) { if (folder === workspaceFolder) { workspaceFolders.unshift(folder); // monitored folder should be first so its sources take precendece } else { workspaceFolders.push(folder); } } const commands = await vscode.commands.getCommands(); const hasNblsProjectSourceRootsCommand = commands.includes(NBLS_GET_SOURCE_ROOTS_COMMAND); const jdtApi = vscode.extensions.getExtension(JDT_EXTENSION_ID)?.exports; if (!hasNblsProjectSourceRootsCommand && !jdtApi?.getProjectSettings) { logUtils.logWarning('[projectUtils] No Java support to compute source roots'); // TODO: wait for NBLS/JDT if installed return undefined; // No Java support available } const hasNblsProjectInfoCommand = commands.includes(NBLS_PROJECT_INFO_COMMAND); const hasMicronautToolsSubprojectCommand = commands.includes(MICRONAUT_TOOLS_SELECTED_SUBPROJECT_COMMAND); const sourceRoots: string[] = []; const getUriSourceRoots = hasNblsProjectSourceRootsCommand ? getUriSourceRootsNbls : getUriSourceRootsJdt; logUtils.logInfo(`[projectUtils] Using ${hasNblsProjectSourceRootsCommand ? 'NBLS' : 'JDT'} to compute source roots`); for (const folder of workspaceFolders) { const unrecognizedProjectFolders: vscode.Uri[] = []; try { const foundSourceRoots = await getUriSourceRoots(sourceRoots, folder, folder.uri.toString(), hasNblsProjectInfoCommand, hasMicronautToolsSubprojectCommand, jdtApi); if (!foundSourceRoots && (!hasNblsProjectSourceRootsCommand || !isSupportedProjectUri(folder.uri))) { // Workaround to allow deep search when using JDT, fixes GDK & JDT without Micronaut Tools unrecognizedProjectFolders.push(folder.uri); } } catch (err) { logUtils.logError(`[projectUtils] Error computing source roots: ${err}`); } // Try to find a nested supported project folder while (unrecognizedProjectFolders.length) { const unrecognizedProjectFolder = unrecognizedProjectFolders.shift(); if (unrecognizedProjectFolder) { const subfolders = fs.readdirSync(unrecognizedProjectFolder.fsPath); for (const subfolder of subfolders) { const subfolderUri = vscode.Uri.joinPath(unrecognizedProjectFolder, subfolder); if (fs.lstatSync(subfolderUri.fsPath)?.isDirectory()) { const foundSourceRoots = await getUriSourceRoots(sourceRoots, folder, subfolderUri.toString(), hasNblsProjectInfoCommand, hasMicronautToolsSubprojectCommand, jdtApi); if (!foundSourceRoots && (!hasNblsProjectSourceRootsCommand || !isSupportedProjectUri(subfolderUri))) { // Workaround to allow deep search when using JDT, fixes GDK & JDT without Micronaut Tools unrecognizedProjectFolders.push(subfolderUri); } } } } } } logUtils.logInfo(`[projectUtils] Found ${sourceRoots.length} source root(s)`); return sourceRoots; } async function getUriSourceRootsNbls(sourceRoots: string[], folder: vscode.WorkspaceFolder, uri: string, hasNblsProjectInfoCommand: boolean, hasMicronautToolsSubprojectCommand: boolean): Promise { let foundSourceRoots = false; const uriSourceRoots: string[] | undefined = await vscode.commands.executeCommand(NBLS_GET_SOURCE_ROOTS_COMMAND, uri); if (uriSourceRoots) { if (uriSourceRoots.length) { // found project source roots foundSourceRoots = true; for (const uriSourceRoot of uriSourceRoots) { const sourceRoot = vscode.Uri.parse(uriSourceRoot).fsPath; if (!sourceRoots.includes(sourceRoot)) { sourceRoots.push(sourceRoot); } } } else { // no project source roots found, may be a modular (GCN) project let selectedSubproject: string | undefined = undefined; if (hasMicronautToolsSubprojectCommand) { // modules selected in Micronaut Tools should be first so their sources take precendece const subprojectUri = await vscode.commands.executeCommand(MICRONAUT_TOOLS_SELECTED_SUBPROJECT_COMMAND, folder); if (subprojectUri instanceof vscode.Uri) { // folder tracked by Micronaut Tools and module selected selectedSubproject = subprojectUri.fsPath; } } if (hasNblsProjectInfoCommand) { const infos: any[] = await vscode.commands.executeCommand(NBLS_PROJECT_INFO_COMMAND, uri, { projectStructure: true }); if (infos?.length && infos[0]) { // multimodule - most likely GCN const subprojects = []; for (const subproject of infos[0].subprojects) { if (vscode.Uri.parse(subproject).fsPath === selectedSubproject) { // add source roots for module selected in Micronaut Tools first subprojects.unshift(subproject); } else { subprojects.push(subproject); } } for (const subproject of subprojects) { foundSourceRoots = await getUriSourceRootsNbls(sourceRoots, folder, subproject, false, false) || foundSourceRoots; // false prevents deep search (OK for GCN, may need to be enabled for other projects) } } } } } return foundSourceRoots; } // TODO: add support for modules/subprojects (for example GDK project and Micronaut Tools ext. not installed) // NOTE: modules/subprojects are defined by the Micronaut Tools ext., which has NBLS as a required dependency -> getUriSourceRootsNbls will be executed instead of getUriSourceRootsJdt async function getUriSourceRootsJdt(sourceRoots: string[], _folder: vscode.WorkspaceFolder, uri: string, _hasNblsProjectInfoCommand: boolean, _hasMicronautToolsSubprojectCommand: boolean, api: any): Promise { let foundSourceRoots = false; try { const settings = await api.getProjectSettings(uri, [ JDT_SETTINGS_SOURCE_PATHS ]); if (settings) { const uriSourceRoots = settings[JDT_SETTINGS_SOURCE_PATHS]; if (uriSourceRoots?.length) { foundSourceRoots = true; for (const uriSourceRoot of uriSourceRoots) { if (!sourceRoots.includes(uriSourceRoot)) { sourceRoots.push(uriSourceRoot); } } } } return foundSourceRoots; } catch (err) { // Error: Given URI does not belong to any Java project. return false; } } export async function getPackages(workspaceFolder?: vscode.WorkspaceFolder): Promise { logUtils.logInfo(`[projectUtils] Computing packages${workspaceFolder ? ' for folder ' + workspaceFolder.uri.fsPath : ''}...`); const workspaceFolders = workspaceFolder ? [ workspaceFolder ] : vscode.workspace.workspaceFolders; if (!workspaceFolders?.length) { // No folder opened logUtils.logInfo('[projectUtils] No folder opened'); return []; } const commands = await vscode.commands.getCommands(); const hasNblsProjectPackagesCommand = commands.includes(NBLS_GET_PACKAGES_COMMAND); const hasJdtWorkspaceCommand = commands.includes(JDT_EXECUTE_WORKSPACE_COMMAND); if (!hasNblsProjectPackagesCommand && !hasJdtWorkspaceCommand) { logUtils.logWarning('[projectUtils] No Java support to compute packages'); // TODO: wait for NBLS/JDT if installed return undefined; // No Java support available } const hasNblsProjectInfoCommand = commands.includes(NBLS_PROJECT_INFO_COMMAND); const hasMicronautToolsSubprojectCommand = commands.includes(MICRONAUT_TOOLS_SELECTED_SUBPROJECT_COMMAND); const packages: string[] = []; const getUriPackages = hasNblsProjectPackagesCommand ? getUriPackagesNbls : getUriPackagesJdt; logUtils.logInfo(`[projectUtils] Using ${hasNblsProjectPackagesCommand ? 'NBLS' : 'JDT'} to compute packages`); for (const folder of workspaceFolders) { const unrecognizedProjectFolders: vscode.Uri[] = []; try { const foundPackages = await getUriPackages(packages, folder, folder.uri.toString(), hasNblsProjectInfoCommand, hasMicronautToolsSubprojectCommand); if (!foundPackages && (!hasNblsProjectPackagesCommand || !isSupportedProjectUri(folder.uri))) { // Workaround to allow deep search when using JDT, fixes GDK & JDT without Micronaut Tools unrecognizedProjectFolders.push(folder.uri); } } catch (err) { logUtils.logError(`[projectUtils] Error computing packages: ${err}`); } // Try to find a nested supported project folder while (unrecognizedProjectFolders.length) { const unrecognizedProjectFolder = unrecognizedProjectFolders.shift(); if (unrecognizedProjectFolder) { const subfolders = fs.readdirSync(unrecognizedProjectFolder.fsPath); for (const subfolder of subfolders) { const subfolderUri = vscode.Uri.joinPath(unrecognizedProjectFolder, subfolder); if (fs.lstatSync(subfolderUri.fsPath)?.isDirectory()) { const foundPackages = await getUriPackages(packages, folder, subfolderUri.toString(), hasNblsProjectInfoCommand, hasMicronautToolsSubprojectCommand); if (!foundPackages && (!hasNblsProjectPackagesCommand || !isSupportedProjectUri(subfolderUri))) { // Workaround to allow deep search when using JDT, fixes GDK & JDT without Micronaut Tools unrecognizedProjectFolders.push(subfolderUri); } } } } } } logUtils.logInfo(`[projectUtils] Found ${packages.length} package(s)`); return packages; } async function getUriPackagesNbls(packages: string[], folder: vscode.WorkspaceFolder, uri: string, hasNblsProjectInfoCommand: boolean, hasMicronautToolsSubprojectCommand: boolean): Promise { let foundPackages = false; const uriPackages: string[] | undefined = await vscode.commands.executeCommand(NBLS_GET_PACKAGES_COMMAND, uri, true); if (uriPackages) { if (uriPackages.length) { // found project packages foundPackages = true; for (const uriPackage of uriPackages) { const wildcardPackage = uriPackage + '.*'; if (!packages.includes(wildcardPackage)) { packages.push(wildcardPackage); } } } else { // no project packages found, may be a modular (GCN) project if (hasMicronautToolsSubprojectCommand) { // include only packages of the module selected in Micronaut Tools const subprojectUri = await vscode.commands.executeCommand(MICRONAUT_TOOLS_SELECTED_SUBPROJECT_COMMAND, folder); if (subprojectUri instanceof vscode.Uri) { // folder tracked by Micronaut Tools and module selected return await getUriPackagesNbls(packages, folder, subprojectUri.toString(), false, false); // false prevents deep search (OK for GCN, may need to be enabled for other projects) // TODO: include dependency subprojects (oci -> lib)? } } if (hasNblsProjectInfoCommand) { // include packages from all found modules const infos: any[] = await vscode.commands.executeCommand(NBLS_PROJECT_INFO_COMMAND, uri, { projectStructure: true }); if (infos?.length && infos[0]) { for (const subproject of infos[0].subprojects) { // multimodule - most likely GCN foundPackages = await getUriPackagesNbls(packages, folder, subproject, false, false) || foundPackages; // false prevents deep search (OK for GCN, may need to be enabled for other projects) } } } } } return foundPackages; } // TODO: add support for modules/subprojects (for example GDK project and Micronaut Tools ext. not installed) // NOTE: modules/subprojects are defined by the Micronaut Tools ext., which has NBLS as a required dependency -> getUriPackagesNbls will be executed instead of getUriPackagesJdt async function getUriPackagesJdt(packages: string[], _folder: vscode.WorkspaceFolder, uri: string): Promise { let foundPackages = false; try { const projectEntries = await getPackageDataJdt({ kind: 2, projectUri: uri }); for (const projectEntry of projectEntries) { if (projectEntry.entryKind === 1) { // source root const packageRoots = await getPackageDataJdt({ kind: 3, projectUri: uri, rootPath: projectEntry.path, isHierarchicalView: false }); for (const packageRoot of packageRoots) { if (packageRoot.kind === 4) { // package root foundPackages = true; const wildcardPackage = packageRoot.name + '.*'; if (!packages.includes(wildcardPackage)) { packages.push(wildcardPackage); } } } } } return foundPackages; } catch (err) { // Error: Did not find container for URI return false; } } async function getPackageDataJdt(params: { [key: string]: any }): Promise { return await vscode.commands.executeCommand(JDT_EXECUTE_WORKSPACE_COMMAND, JDT_GET_PACKAGE_DATA, params) || []; } // Currently supports recognizing Maven Java project root (pom.xml) and Gradle Java project root (settings.gradle or build.gradle) // Ideally a NBLS / JDT API should be used to identify a project folder supported by the particular LS function isSupportedProjectUri(uri: vscode.Uri): boolean { const mavenPomFile = path.join(uri.fsPath, 'pom.xml'); if (fs.existsSync(mavenPomFile) && fs.lstatSync(mavenPomFile)?.isFile()) { return true; } const gradleSettingsFile = path.join(uri.fsPath, 'settings.gradle'); if (fs.existsSync(gradleSettingsFile) && fs.lstatSync(gradleSettingsFile)?.isFile()) { return true; } const gradleBuildFile = path.join(uri.fsPath, 'build.gradle'); if (fs.existsSync(gradleBuildFile) && fs.lstatSync(gradleBuildFile)?.isFile()) { return true; } return false; } ================================================ FILE: integrations/vscode/src/runningProcesses.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as cp from 'child_process'; import * as jdk from './jdk'; import * as parameters from './parameters'; // import * as logUtils from './logUtils'; export type RunningProcess = { readonly pid: number; readonly displayName: string; }; export async function select(ignore?: number[]): Promise { const jdkPath = await jdk.getPath(); if (!jdkPath) { return undefined; } const jpsPath = jdk.getJpsPath(jdkPath); if (!jpsPath) { return undefined; } try { const processes: Promise = new Promise(async (resolve) => { const parts1 = await getUsingJps(jpsPath, '-v'); const parts2 = await getUsingJps(jpsPath, '-lm'); const processes: QuickPickProcess[] = []; parts1.forEach(p1 => { const p2 = parts2.find(p2 => p2.pid === p1.pid); if (p2 && !ignore?.includes(p2.pid) && !p2.displayName.includes('--branding visualvm')) { // TODO: filter out jps process processes.push(new QuickPickProcess(p1.pid, p1.displayName, p2.displayName)); } }); resolve(processes); }); const selected = await vscode.window.showQuickPick(processes, { title: 'Select Running Java Process', placeHolder: 'Select the process to be monitored by VisualVM' }); if (selected) { return { pid: selected.pid, displayName: selected.label }; } else { return undefined; } } catch (err) { vscode.window.showErrorMessage(`Failed to read running Java processes: ${err}`); return undefined; } } class QuickPickProcess implements vscode.QuickPickItem{ label: string; description: string; detail?: string; constructor(public readonly pid: number, info1: string, info2: string) { this.label = ''; const infos1 = info1.split(' '); const vmArgDisplayName = parameters.vmArgDisplayName('', false); for (const info of infos1) { if (info.startsWith(vmArgDisplayName)) { this.label = info.substring(vmArgDisplayName.length).replace(/\%PID/g, '').replace(/\%pid/g, ''); break; } } this.label = this.label || infos1[0] || 'Java Process'; this.description = `(pid ${pid})`; this.detail = this.normalize(info2 || info1 || 'no details available', 1000); // VS Code fails to display long string in tooltip } private normalize(string: string, limit: number): string { string = string.trim(); const length = string.length; return length <= limit ? string : string.substring(0, limit); } } export async function getUsingJps(jpsPath: string, command: string = '-v'): Promise { return new Promise((resolve, reject) => { const cmd = `"${jpsPath}" ${command}`; cp.exec(cmd, async (error: any, stdout: string) => { if (error) { reject(error); } const lines = stdout.split('\n'); const parts: RunningProcess[] = []; lines.forEach(line => { const index = line.trim().indexOf(' '); if (index >= 0) { parts.push({ pid: Number.parseInt(line.slice(0, index)), displayName: line.slice(index + 1, line.length).trim() }); } else { parts.push({ pid: Number.parseInt(line), displayName: '' }); } }); resolve(parts); }); }); } const SEARCH_PROCESSES_TIMEOUT = 120; // [s] Time to search for a process before triggering onTimeout() const SEARCH_PROCESSES_INTERVAL = 1000; // [ms] Interval between calling the jps command const SEARCHED_PROCESSES: SearchedProcess[] = []; let SEARCH_PROCESSES_JPS_PATH: string | undefined; type SearchedProcess = { searchParameter: string; onFound: (pid: number) => void; onTimeout: () => void; timeoutTime: number; // timestamp after which onTimeout() will be triggered }; export function setJpsPath(jpsPath: string) { SEARCH_PROCESSES_JPS_PATH = jpsPath; } export async function searchByParameter(searchParameter: string, onFound: (pid: number) => void, onTimeout: () => void, searchTimeout: number = SEARCH_PROCESSES_TIMEOUT * 1000) { SEARCHED_PROCESSES.push({ searchParameter: searchParameter, onFound: onFound, onTimeout: onTimeout, timeoutTime: Date.now() + searchTimeout }); if (SEARCHED_PROCESSES.length === 1) { searchProcesses(); } } export function stopSearching(searchParameter: string) { for (let index = 0; index < SEARCHED_PROCESSES.length; index++) { if (SEARCHED_PROCESSES[index].searchParameter === searchParameter) { SEARCHED_PROCESSES.splice(index, 1); break; } } } function searchProcesses() { const now = Date.now(); for (let index = SEARCHED_PROCESSES.length - 1; index >= 0; index--) { const process = SEARCHED_PROCESSES[index]; if (process.timeoutTime <= now) { setTimeout(() => { process.onTimeout(); }, 0); SEARCHED_PROCESSES.splice(index, 1); } } if (SEARCHED_PROCESSES.length) { if (SEARCH_PROCESSES_JPS_PATH) { getUsingJps(SEARCH_PROCESSES_JPS_PATH).then(results => { if (results.length) { for (let index = SEARCHED_PROCESSES.length - 1; index >= 0; index--) { const process = SEARCHED_PROCESSES[index]; for (const result of results) { if (result.displayName.includes(process.searchParameter)) { setTimeout(() => { process.onFound(result.pid); }, 0); SEARCHED_PROCESSES.splice(index, 1); break; } } } } if (SEARCHED_PROCESSES.length) { setTimeout(() => { searchProcesses(); }, SEARCH_PROCESSES_INTERVAL); } }); } } } ================================================ FILE: integrations/vscode/src/test/README.md ================================================ # Proxy setup In case of network behind the proxy, the following variables must be set: - `http_proxy` - URL to proxy, incl. protocol and port, e.g. http://acme.com:80 - `no_proxy` - URL patterns that must not use proxy. In particular, corporate/internal NPM module repositories must be enumerated in no_proxy env var. Internally (in package.json), the globalAgent/bootstrap is used with `GLOBAL_AGENT_{HTTP,NO}_PROXY` set to the appropriate env variable. The environment variables `http_proxy` and `no_proxy` are read by npm package manager. # Prepare for testing Ensure that all necessary npm modules are installed. Run - `npm install` to update the local node_modules module cache, if any changes were pulled for `package.json`. You need to compile the VisualVM extension itself, and the test code before launching the tests. - `npm run compile` - `npm run pretest` # Run the tests from the CLI Tests can be executed by `npm run test`. The test bootstrap will download a separate installation of vscode into `.vscode-test` directory and then duplicated into `output/a vscode-test` to test the space in path of vscode installation. The testing environment will use a **separate** extensions dir (`.vscode-test/extensions`) and user dir (`.vscode-test/user-data`). The tested vscode installation is completely separated from the development one. ================================================ FILE: integrations/vscode/src/test/runTest.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import { downloadAndUnzipVSCode, runTests } from '@vscode/test-electron'; import * as path from 'path'; import * as fs from 'fs'; async function main() { try { // The folder containing the Extension Manifest package.json // Passed to `--extensionDevelopmentPath` const extensionDevelopmentPath = path.resolve(__dirname, '../../'); // The path to the extension test runner script // Passed to --extensionTestsPath const extensionTestsPath = path.resolve(__dirname, './suite/index'); // The path to the test project const testWorkspace = path.resolve(__dirname, '../../fixtures/test projects/demo'); // Manually download latest stable VS Code release for testing. const vscodeExecutablePath = await downloadAndUnzipVSCode('1.89.0'); const outputFolder = path.resolve(__dirname, '../../output'); if (!fs.existsSync(outputFolder)) { fs.mkdirSync(outputFolder); } const noSpacePath = path.resolve(__dirname, '../../.vscode-test'); const spacePath = path.resolve(__dirname, '../../output/a vscode-test'); const splitPath = vscodeExecutablePath.split('\\'); const exeFile = splitPath.pop(); const vscodeFolder = splitPath.pop(); let newVscodeExecutablePath: string = vscodeExecutablePath; if (vscodeFolder && exeFile) { newVscodeExecutablePath = path.join(spacePath, vscodeFolder, exeFile); } if (!fs.existsSync(spacePath)) { duplicate(noSpacePath, spacePath); } await runTests({ vscodeExecutablePath: newVscodeExecutablePath, extensionDevelopmentPath, extensionTestsPath, launchArgs: [testWorkspace] }); } catch (err) { console.error(err); console.error('Failed to run tests'); process.exit(1); } } main(); function duplicate(sourceFolder: string, targetFolder: string) { if (!fs.existsSync(targetFolder)) { fs.mkdirSync(targetFolder); } const content = fs.readdirSync(sourceFolder); content.forEach((element) => { const sourcePath = path.join(sourceFolder, element); const targetPath = path.join(targetFolder, element); if (fs.lstatSync(sourcePath).isDirectory()) { duplicate(sourcePath, targetPath); } else { fs.copyFileSync(sourcePath, targetPath); } }); } ================================================ FILE: integrations/vscode/src/test/suite/download.test.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import { downloadLatestVisualVM, getReleaseMetadata } from '../../download'; import * as assert from 'assert'; import * as vscode from 'vscode'; import { clean } from './utils'; import * as path from 'path'; import * as fs from 'fs'; suite('Download Tests', async function () { let returnPath: string|undefined; test('Download Success (Home Path)', async function() { this.timeout(300000); // Time needed to download VisualVM // Creating the mocking Path const outputPath = path.resolve(__dirname, '../../../output'); const superFolder : string = vscode.Uri.file(outputPath).fsPath; // Before download check const releaseMetadata = await getReleaseMetadata(); assert(releaseMetadata, 'No release meta data found.'); // Download in the mocking Path returnPath = await downloadLatestVisualVM(superFolder); assert(returnPath, 'The downloadLatestVisualVM() function does not return any Path.'); // Get The operating system const opsys = process.platform; // Asserts if (opsys !== 'darwin'){ // Check if the VisualVM executable exists assert.strictEqual(fs.existsSync(path.join(returnPath, 'bin', 'visualvm.exe')), true, 'Executable file does not exist.'); // Check if the VisualVM startup jar file exists assert.strictEqual(fs.existsSync(path.join(returnPath, 'visualvm', 'core', 'org-graalvm-visualvm-modules-startup.jar')), true, 'Startup jar file does not exist.'); // Check if the VisualVM Go to source jar file exists assert.strictEqual(fs.existsSync(path.join(returnPath, 'visualvm', 'modules', 'org-graalvm-visualvm-gotosource.jar')), true, 'Go to source jar file does not exist.'); // Check if the installation path set to workspace configuration assert.strictEqual(returnPath, vscode.workspace.getConfiguration().get('visualvm.installation.visualvmPath'), 'The installation path has not been configured in the workspace settings.'); } else{ // Check if installation file exists assert.strictEqual(fs.existsSync(returnPath), true, 'VisualVM dmg file does not exist after download.'); } // Clean the test installation await clean(returnPath); }); // this.afterAll(async () => { // assert(returnPath); // }); }); ================================================ FILE: integrations/vscode/src/test/suite/extension.test.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as assert from 'assert'; import * as vscode from 'vscode'; suite('Extension Test Suite', () => { test('Extension loaded', async () => { // Get the extension using vscode API and ID let extension = vscode.extensions.getExtension('oracle-labs-graalvm.visualvm-vscode'); assert(extension, 'No VisualVM extension found!'); // Waiting for activating the extension await extension.activate(); }); test('VisualVM commands loaded', async () => { // Load all vscode commands let commands = await vscode.commands.getCommands(true); // Check for VisualVM commands let containsVisualVMCommands = false; for (const command of commands){ if (command.indexOf('visualvm.') === 0) containsVisualVMCommands = true; } assert(containsVisualVMCommands, 'No VisualVM command has been loaded'); }); }); ================================================ FILE: integrations/vscode/src/test/suite/index.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as path from 'path'; import * as glob from 'glob'; import * as Mocha from 'mocha'; export function run(): Promise { // Create the mocha test const mocha = new Mocha({ ui: 'tdd', color: true, reporter: 'mochawesome' }); const testsRoot = path.resolve(__dirname, '..'); const globPattern = process.env['TEST_GLOB_PATTER'] ? process.env['TEST_GLOB_PATTER'] : '**/*.test.js'; console.log(globPattern); return new Promise((c, e) => { glob(globPattern, { cwd: testsRoot }, (err, files) => { if (err) { return e(err); } // Add files to the test suite files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); try { // Run the mocha test mocha.run(failures => { if (failures > 0) { e(new Error(`${failures} tests failed.`)); } else { c(); } }); } catch (err) { console.error(err); e(err); } }); }); } ================================================ FILE: integrations/vscode/src/test/suite/utils.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import { downloadLatestVisualVM, getReleaseMetadata } from '../../download'; import * as cp from 'child_process'; import * as vscode from 'vscode'; import * as assert from 'assert'; import * as path from 'path'; import * as fs from 'fs'; export async function setupSelectEnvironment() { // Before download check const releaseMetadata = await getReleaseMetadata(); assert(releaseMetadata, 'No release meta data found.'); const outputPath = path.resolve(__dirname, '../../../output'); const dirPath = path.join(outputPath, 'visualvm-test'); const firstSubDirPath = path.join(outputPath, 'visualvm-test', 'version 1'); const secondSubDirPath = path.join(outputPath, 'visualvm-test', 'version 2'); await fs.promises.mkdir(dirPath); await fs.promises.mkdir(firstSubDirPath); await fs.promises.mkdir(secondSubDirPath); const firstFinalPath : string = vscode.Uri.file(firstSubDirPath).fsPath; const secondFinalPath : string = vscode.Uri.file(secondSubDirPath).fsPath; const firstReturnPath = await downloadLatestVisualVM(firstFinalPath); assert(firstReturnPath, 'VisualVM download failed'); const secondReturnPath = await downloadLatestVisualVM(secondFinalPath); assert(secondReturnPath, 'VisualVM download failed'); const returnPaths = { 'dirPath': dirPath, 'firstReturnPath' : firstReturnPath, 'secondReturnPath' : secondReturnPath }; return returnPaths; } export async function clean(yourPath: string) { try{ await fs.promises.rm(yourPath, { recursive: true }); } catch (error) { console.error(`Can't delete directory: ${error}`); } } export async function installExtensions(): Promise { const redhatPath = path.resolve(__dirname, '../../../.vscode-test/extensions/redhat.java*'); const nblsPath = path.resolve(__dirname, '../../../.vscode-test/extensions/asf.apache-netbeans-java*'); const redhat = fs.existsSync(redhatPath); const nbls = fs.existsSync(nblsPath); if ( !redhat ) { try { await vscode.commands.executeCommand('workbench.extensions.installExtension', 'redhat.java'); } catch (error) { console.error('Can\'t install Redhat Java extension: ', error); } } if ( !nbls ) { try { await vscode.commands.executeCommand('workbench.extensions.installExtension', 'asf.apache-netbeans-java'); } catch (error) { console.error('Can\'t install Netbeans Language Server extension: ', error); } } await waitForExtensionsToFinish(); } async function waitForExtensionsToFinish(): Promise { return new Promise((resolve) => { const interval = setInterval(() => { const nblsExtension = vscode.extensions.getExtension('asf.apache-netbeans-java'); const redhatExtension = vscode.extensions.getExtension('redhat.java'); if (nblsExtension && redhatExtension) { clearInterval(interval); resolve(); } }, 20000); }); } export function duplicate(sourceFolder: string, targetFolder: string) { if (!fs.existsSync(targetFolder)) { fs.mkdirSync(targetFolder); } const content = fs.readdirSync(sourceFolder); content.forEach((element) => { const sourcePath = path.join(sourceFolder, element); const targetPath = path.join(targetFolder, element); if (fs.lstatSync(sourcePath).isDirectory()) { duplicate(sourcePath, targetPath); } else { fs.copyFileSync(sourcePath, targetPath); } }); } export async function buildJavaProject (pathToProject: string) { // Check maven existence cp.exec('mvn -v', (error) => { if (error) { console.error(`Check MAVEN installation :: Error checking Maven installation: ${error.message}`); } }); return new Promise ((resolve, reject) => { cp.exec('mvn clean install', { cwd: pathToProject }, (error) => { if (error) { console.log(`Error executing Maven build: ${error.message}`); reject(error); return; } resolve(); }); }); } ================================================ FILE: integrations/vscode/src/test/suite/visualvm.test.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import { cpuSamplerStart, encode, getJdkSourceRoots, getTmpDir, getWorkspaceSourceRoots, goToSource, heapDump, jdkHome, jfrRecordingDump, jfrRecordingStart, jfrRecordingStop, memorySamplerStart, openPid, resolveSamplingFilter, samplerSnapshot, samplerStop, threadDump, vmArgDisplayName, vmArgId } from '../../parameters'; import { buildJavaProject, clean,duplicate,installExtensions, setupSelectEnvironment } from './utils'; import { getUsingJps } from '../../runningProcesses'; import { getPath, getJpsPath } from '../../jdk'; import { getSourceRoots } from '../../projectUtils'; import { findLauncher } from '../../vscodeUtils'; import { invoke, select} from '../../visualvm'; import * as cp from 'child_process'; import * as assert from 'assert'; import * as vscode from 'vscode'; import * as path from 'path'; import * as fs from 'fs'; // Get work space folders let wf = vscode.workspace.workspaceFolders; suite('VisualVM Suite Tests', function () { // The timeout will propagate to setup dependencies and tests this.timeout(1000000); this.beforeAll(async () => { this.timeout(1000000); // Install NBLS & JDT await installExtensions(); // wait for build project const projectPath = path.resolve(__dirname, '../../../fixtures/test projects/demo'); await buildJavaProject(projectPath); }); let downloadPaths: { firstReturnPath: string; dirPath: string; secondReturnPath: string}; test('Select new visualvm done', async function () { // Setup a test environment downloadPaths = await setupSelectEnvironment(); // Alter the path to which VisualVM is pointing await select(downloadPaths.firstReturnPath); // Get from vscode conf. the actual VisualVM path const actualPath = vscode.workspace.getConfiguration().get('visualvm.installation.visualvmPath'); // Check if the current path matches the expected path assert.strictEqual(actualPath, downloadPaths.firstReturnPath); }); let jdk: string | undefined; test('Prerequisites done', async function () { // JDK configuration jdk = await jdkHome(); assert(jdk, 'no JDK available'); // Workspace and java project opened assert(wf, 'workspace not found'); assert(wf[0].uri.toString(), 'project not found'); // Source Roots resolved const sourceRoot = await getSourceRoots(wf[0]); assert(sourceRoot, 'source root not found'); }); let testPid: number = 0; // pid of a test Java process let visualvmPid: number = 0; // pid of a VisualVM process test('Manually Selecting Project Process', async function () { this.timeout(20000); const projectPath = path.resolve(__dirname, '../../../fixtures/test projects/demo'); // Run Java Project const TEST_JAVA_PROCESS_PARAMETER = '-Dtest.java.process=true'; try { const jarFilePath = path.join(projectPath, 'oci/target/oci-1.0-SNAPSHOT.jar'); if (fs.existsSync(jarFilePath)) { cp.spawn('java', [TEST_JAVA_PROCESS_PARAMETER, '-jar', 'oci/target/oci-1.0-SNAPSHOT.jar'], { cwd: projectPath }); } else { assert(undefined, 'JAR File does not exist ... The build does not done correctly'); } } catch (error) { console.error('Error running JAR file:', error); } // Wait for the test process to fully start await new Promise(f => setTimeout(f, 1500)); const jdkPath = await getPath(false); assert(jdkPath, 'no JDK available'); const jpsPath = getJpsPath(jdkPath); assert(jpsPath, 'no jps available'); const processes = await getUsingJps(jpsPath); assert(processes, 'Can\'t get running java processes'); let isProcessExist: boolean = false; for (const process of processes) { if (process.displayName.includes(TEST_JAVA_PROCESS_PARAMETER)) { isProcessExist = true; testPid = process.pid; break; } } assert.strictEqual(isProcessExist, true, 'Java test process not found !'); }); test('CPU Sampler Configuration Correctly Generated', async () => { assert(wf); const projectClasses = await resolveSamplingFilter('include-classes', wf[0]); assert(projectClasses, 'Any project classes resolved'); const samplingRateP = `sampling-rate=1000`; const suffix = '--start-cpu-sampler '+testPid+'@'; const withoutFile = projectClasses+','+samplingRateP; const expectedParameterWithoutFile = suffix+withoutFile; const tmp = getTmpDir(); assert(tmp, 'Can\'t get tmp directory'); const confFile = path.join(tmp, 'visualvm-sampler-config'); assert(confFile); const withFile = `settings-file="${confFile}"`; const expectedParameterWithFile = `${suffix+withFile}`; // cases : exclude-classes - include-classes - default const visualvmParameter = await cpuSamplerStart(testPid, 'include-classes', 1000, wf[0]); assert(visualvmParameter, 'CPU Sampler can\'t start'); if (projectClasses.length + samplingRateP.length > 200) { assert.strictEqual(visualvmParameter, expectedParameterWithFile); } else { assert.strictEqual(visualvmParameter, expectedParameterWithoutFile); } }); test('Go to Source Configuration Correctly Generated', async () => { assert(wf); const jdkSourceRoot = await getJdkSourceRoots(); assert(jdkSourceRoot, 'Can\'t get jdk source roots'); const workspaceSourceRoots = await getWorkspaceSourceRoots(wf[0]); assert(workspaceSourceRoots, 'Can\'t get work space source roots'); workspaceSourceRoots.push(jdkSourceRoot); const launcher = findLauncher(); assert(launcher, 'Can\'t found vs code launcher'); const vsCodeLauncherParameters = vscode.workspace.getConfiguration().get('visualvm.integration.visualStudioCodeParameters', ''); let firstParamName: string = ''; let secondParamName: string = ''; const params = vsCodeLauncherParameters ? ' ' + vsCodeLauncherParameters : ''; const sourceRouts = workspaceSourceRoots.join(path.delimiter); const notFinalSourceViewer = `=${encode(`${launcher}${params}`)} -g {file}:{line}:{column}`; const notFinalSourceRoots = `=${sourceRouts}`; let expectedParameters: string = ''; let finalSourceRoots: string = ''; let finalSourceViewer: string = ''; // invoke go to source const parameters = await goToSource(wf[0]); assert(parameters); if (notFinalSourceViewer.length + notFinalSourceRoots.length > 201) { firstParamName = 'source-viewer'; secondParamName = 'source-roots'; finalSourceRoots = secondParamName+notFinalSourceRoots.replace(/\\/g, '\\\\') + '\n'; finalSourceViewer = firstParamName+notFinalSourceViewer.replace(/\\/g, '\\\\') + '\n'; expectedParameters = finalSourceViewer+finalSourceRoots; const tmp = getTmpDir(); assert(tmp, 'Can\'t get tmp directory'); const confFile = path.join(tmp, 'visualvm-source-config'); assert(confFile); const expectedReturn = `--source-config="${encode(confFile)}"`; assert.strictEqual(expectedReturn, parameters); let contentOfFile = fs.readFileSync(confFile, 'utf8'); assert.strictEqual(expectedParameters, contentOfFile, 'parameters not set correctly'); } else { firstParamName = '--source-viewer'; secondParamName = '--source-roots'; expectedParameters = `${firstParamName}${notFinalSourceViewer} ${secondParamName}${notFinalSourceRoots}`; assert(expectedParameters ,parameters); } }); test('Test open process', () => { const parameter = openPid(testPid); assert.strictEqual(parameter, `--openpid ${testPid.toString()}@2`, 'Test open process failed'); }); test('Test thread Dump', () => { const parameter = threadDump(testPid); assert.strictEqual(parameter, `--threaddump ${testPid.toString()}`, 'Test thread Dump failed'); }); test('Test heap Dump', () => { const parameter = heapDump(testPid); assert.strictEqual(parameter, `--heapdump ${testPid.toString()}`, 'Test heap Dump failed'); }); test('Test memory Sampler Start', () => { const parameter = memorySamplerStart(testPid, 2000); assert.strictEqual(parameter, `--start-memory-sampler ${testPid}@sampling-rate=2000`, 'Test memory Sampler Start failed'); }); test('Test sampler Snapshot', () => { const parameter = samplerSnapshot(testPid); assert.strictEqual(parameter, `--snapshot-sampler ${testPid.toString()}`, 'Test sampler Snapshot failed'); }); test('Test sampler Stop', () => { const parameter = samplerStop(testPid); assert.strictEqual(parameter, `--stop-sampler ${testPid.toString()}`, 'Test sampler Stop failed'); }); test('Test jfr Recording Start', () => { const parameter = jfrRecordingStart(testPid, 'my jfr', 'profile1'); assert.strictEqual(parameter, `--start-jfr ${testPid.toString()}@name=my%20jfr,settings=profile1`, 'Test jfr Recording Start failed'); }); test('Test jfr Recording Dump', () => { const parameter = jfrRecordingDump(testPid); assert.strictEqual(parameter, `--dump-jfr ${testPid.toString()}`, 'Test jfr Recording Dump failed'); }); test('Test jfr Recording Stop', () => { const parameter = jfrRecordingStop(testPid); assert.strictEqual(parameter, `--stop-jfr ${testPid.toString()}`, 'Test jfr Recording Stop failed'); }); test('Test vmArg Id', () => { const parameter = vmArgId('Java_ID'); assert.strictEqual(parameter, `-Dvisualvm.id=Java_ID`, 'Test vmArg Id failed'); }); test('Test vmArg Display Name', () => { const parameter = vmArgDisplayName('Java Process'); assert.strictEqual(parameter, `-Dvisualvm.display.name=Java_Process%PID`, 'Test vmArg Display Name failed'); }); test('Space in Home JDK path Then invoke', async () => { let homeJdkPath = process.env['JAVA_HOME']; if (!homeJdkPath) { homeJdkPath = process.env['JDK_HOME']; } assert(homeJdkPath, 'JDK Home not Configured in your machine'); const spaceMockPath = path.resolve(__dirname, '../../../output/space JDK'); if (!fs.existsSync(spaceMockPath)) { duplicate(homeJdkPath, spaceMockPath); } const spacePath = await jdkHome(spaceMockPath); assert.strictEqual(spacePath, `--jdkhome "${spaceMockPath}"`); assert(wf); const TEST_VISUALVM_PROCESS_PARAMETER = '-Dvisualvm.test.process=true'; const isShow = await invoke(`-J${TEST_VISUALVM_PROCESS_PARAMETER}`, wf[0], spaceMockPath); if (isShow) { await new Promise(f => setTimeout(f, 3000)); const jdkPath = await getPath(false); assert(jdkPath, 'no JDK available'); const jpsPath = getJpsPath(jdkPath); assert(jpsPath, 'no jps available'); const processes = await getUsingJps(jpsPath); assert(processes, 'Can\'t get running java processes'); for (const process of processes) { if (process.displayName.includes(TEST_VISUALVM_PROCESS_PARAMETER)) { visualvmPid = process.pid; break; } } } assert.strictEqual(isShow && !!visualvmPid, true, 'VisualVM can\'t started'); }); this.afterAll(async () => { this.timeout(15000); if (testPid) { try { process.kill(testPid); } catch (err) { console.log(`Failed to kill test process PID=${testPid}: ${err}`) } } if (visualvmPid) { try { process.kill(visualvmPid); } catch (err) { console.log(`Failed to kill visualvm process PID=${visualvmPid}: ${err}`) } } // Wait for a while to have all resources released before the final cleanup await new Promise(f => setTimeout(f, 3000)); // Clean the test installations await clean(downloadPaths.dirPath); }); }); ================================================ FILE: integrations/vscode/src/view.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as nodes from './nodes'; import * as commands from './commands'; import * as logUtils from './logUtils'; // Predefined views const VISUALVM_VIEW_ID = 'visualvm-visualvm'; const EXPLORER_TOOLS_VIEW_ID = 'explorer-visualvm'; const DEBUG_TOOLS_VIEW_ID = 'debug-visualvm'; const PREDEFINED_VIEW_IDS = [ VISUALVM_VIEW_ID, EXPLORER_TOOLS_VIEW_ID, DEBUG_TOOLS_VIEW_ID ]; // Supported external views const MICRONAUT_TOOLS_VIEW: ExternalView = { extension_id: 'oracle-labs-graalvm.micronaut-tools', container_id: 'extension-micronaut-tools', view_id : 'extension-micronaut-tools-visualvm' }; // const SPRING_BOOT_DASHBOARD_VIEW: ExternalView = { // extension_id: 'vscjava.vscode-spring-boot-dashboard', // container_id: 'spring', // view_id : 'spring-visualvm' // }; const EXTERNAL_VIEWS = [ MICRONAUT_TOOLS_VIEW ]; const EXTERNAL_VIEW_IDS = EXTERNAL_VIEWS.map(view => view.view_id); // All views const ALL_VIEW_IDS = [ ...PREDEFINED_VIEW_IDS, ...EXTERNAL_VIEW_IDS ]; type ExternalView = { extension_id: string; container_id: string; view_id : string; }; const VIEW_KEY = 'visualvm.view'; let currentViewId: string | undefined; const ALL_VIEWS_KEY = 'visualvm.views'; const CREATED_VIEWS: any = {}; let persistentStorage: vscode.Memento | undefined; export function initialize(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_MOVE_VIEW, (viewId?: string) => { // NOTE: if called without the viewId parameter, the last selected node is passed as a parameter move(typeof viewId === 'string' ? viewId : undefined); })); let viewId: string | undefined; // For now the view is always persisted in the global storage // In future we may decide to optionally store it per workspace const workspaceViewId = context.workspaceState.get(VIEW_KEY); if (workspaceViewId) { persistentStorage = context.workspaceState; if (PREDEFINED_VIEW_IDS.includes(workspaceViewId)) { viewId = workspaceViewId; logUtils.logInfo(`[view] Restoring predefined view saved for workspace: ${workspaceViewId}`); } else if (EXTERNAL_VIEW_IDS.includes(workspaceViewId)) { if (externalViewAvailable(workspaceViewId)) { viewId = workspaceViewId; logUtils.logInfo(`[view] Restoring external view saved for workspace: ${workspaceViewId}`); } else { logUtils.logWarning(`[view] External view saved for workspace cannot be restored: ${workspaceViewId}`); } } else { logUtils.logWarning(`[view] Unknown view saved for workspace cannot be restored: ${workspaceViewId}`); } } else { logUtils.logInfo('[view] No view saved for workspace'); } if (!viewId) { const globalViewId = context.globalState.get(VIEW_KEY); if (globalViewId) { if (PREDEFINED_VIEW_IDS.includes(globalViewId)) { viewId = globalViewId; logUtils.logInfo(`[view] Restoring predefined view saved globally: ${globalViewId}`); } else if (EXTERNAL_VIEW_IDS.includes(globalViewId)) { if (externalViewAvailable(globalViewId)) { viewId = globalViewId; logUtils.logInfo(`[view] Restoring external view saved globally: ${globalViewId}`); } else { logUtils.logWarning(`[view] External view saved globally cannot be restored: ${globalViewId}`); } } else { logUtils.logWarning(`[view] Unknown view saved globally cannot be restored: ${globalViewId}`); } } else { logUtils.logInfo('[view] No view saved globally'); } } if (!viewId) { viewId = VISUALVM_VIEW_ID; logUtils.logInfo(`[view] Fallback to default view: ${viewId}`); } // For now the view is always persisted in the global storage // In future we may decide to optionally store it per workspace if (!persistentStorage) { persistentStorage = context.globalState; } switchView(viewId); vscode.commands.executeCommand('setContext', ALL_VIEWS_KEY, ALL_VIEW_IDS); } export async function move(viewId?: string): Promise { if (!viewId) { logUtils.logInfo('[view] Selecting view container'); viewId = await selectViewContainer(commands.COMMAND_MOVE_VIEW_NAME); if (!viewId) { logUtils.logInfo('[view] View container selection canceled'); return undefined; } } else { logUtils.logInfo(`[view] Requested to move view: ${viewId}`); if (EXTERNAL_VIEW_IDS.includes(viewId)) { if (!externalViewAvailable(viewId)) { logUtils.logWarning(`[view] External view not available: ${viewId}`); return false; } } else if (!PREDEFINED_VIEW_IDS.includes(viewId)) { logUtils.logWarning(`[view] Unknown view: ${viewId}`); return false; } } if (persistentStorage) { persistentStorage.update(VIEW_KEY, viewId); } switchView(viewId); // Make sure the selected view appears in the expected location await vscode.commands.executeCommand(viewId + '.resetViewLocation'); // Focus the selected view to make sure it's visible await vscode.commands.executeCommand(viewId + '.focus'); return true; } export function hideNodes() { nodes.provider().setVisible(false); } export function showNodes() { nodes.provider().setVisible(true); } export function getViewId(): string { return currentViewId || VISUALVM_VIEW_ID; } async function selectViewContainer(actionName?: string): Promise { const items: (vscode.QuickPickItem & { viewId: string }) [] = []; items.push({ label: 'VisualVM', description: currentViewId === VISUALVM_VIEW_ID ? '(current)' : undefined, viewId: VISUALVM_VIEW_ID }); items.push({ label: 'Explorer', description: currentViewId === EXPLORER_TOOLS_VIEW_ID ? '(current)' : undefined, viewId: EXPLORER_TOOLS_VIEW_ID }); items.push({ label: 'Run and Debug', description: currentViewId === DEBUG_TOOLS_VIEW_ID ? '(current)' : undefined, viewId: DEBUG_TOOLS_VIEW_ID }); if (externalViewAvailable(MICRONAUT_TOOLS_VIEW)) { items.push({ label: 'Micronaut Tools', description: currentViewId === MICRONAUT_TOOLS_VIEW.view_id ? '(current)' : undefined, viewId: MICRONAUT_TOOLS_VIEW.view_id }); } return vscode.window.showQuickPick(items, { title: actionName || 'Select VisualVM View Container', placeHolder: 'Choose the VisualVM view location:' }).then(selected => selected?.viewId); } function externalViewAvailable(view: string | ExternalView): boolean { let externalView = typeof view === 'string' ? findExternalView(view) : view; if (!externalView) { logUtils.logWarning(`[view] Unknown external view: ${view}`); return false; } const extension = vscode.extensions.getExtension(externalView.extension_id); if (extension) { const extensionViews = extension.packageJSON?.contributes?.views?.[externalView.container_id]; if (Array.isArray(extensionViews)) { for (const extensionView of extensionViews) { if (extensionView.id === externalView.view_id) { if (extensionView.name !== 'VisualVM') { logUtils.logWarning(`[view] Extension providing external view defines unsupported view name: ${extensionView.name}`); return false; } if (extensionView.when !== `${VIEW_KEY} == ${externalView.view_id}` && extensionView.when !== `${VIEW_KEY} === ${externalView.view_id}`) { logUtils.logWarning(`[view] Extension providing external view defines unsupported view activation: ${extensionView.when}`); return false; } return true; } } } logUtils.logWarning(`[view] Extension providing external view doesn't define VisualVM view in: ${externalView.container_id}`); } else { logUtils.logWarning(`[view] Extension providing external view not available: ${externalView.extension_id}`); } return false; } function findExternalView(viewId: string): ExternalView | undefined { for (const externalView of EXTERNAL_VIEWS) { if (externalView.view_id === viewId) { return externalView; } } return undefined; } function switchView(viewId: string) { if (!CREATED_VIEWS[viewId]) { CREATED_VIEWS[viewId] = vscode.window.createTreeView(viewId, { treeDataProvider: nodes.provider() }); logUtils.logInfo(`[view] Created view ${viewId}`); } currentViewId = viewId; vscode.commands.executeCommand('setContext', VIEW_KEY, viewId); logUtils.logInfo(`[view] View switched to ${viewId}`); } ================================================ FILE: integrations/vscode/src/visualvm.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as vscode from 'vscode'; import * as os from 'os'; import * as fs from 'fs'; import * as path from 'path'; import * as process from 'process'; import * as cp from 'child_process'; import * as view from './view'; import * as parameters from './parameters'; import * as commands from './commands'; import * as logUtils from './logUtils'; export const VISUALVM_HOMEPAGE = 'https://visualvm.github.io'; const INITIALIZED_KEY = 'visualvm.initialized'; const NO_INSTALLATION_KEY = 'visualvm.noInstallation'; const INSTALLATION_PATH_KEY = 'visualvm.installation.visualvmPath'; type VisualVMInstallation = { executable: string; isGraalVM: boolean; // 1: VisualVM 2.1+ featureSet: number; }; let interactiveChange: boolean = false; export async function initialize(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_SELECT_INSTALLATION, () => { select(); })); context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_START_VISUALVM, () => { show(); })); resolve(); context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(event => { if (event.affectsConfiguration(INSTALLATION_PATH_KEY)) { logUtils.logInfo('[visualvm] Installation path changed'); const interactive = interactiveChange; interactiveChange = false; resolve(interactive); } })); } export async function select(visualVMPath?: string) { const savedVisualVMPath = vscode.workspace.getConfiguration().get(INSTALLATION_PATH_KEY); const savedVisualVMUri = savedVisualVMPath ? vscode.Uri.file(savedVisualVMPath) : undefined; if (!visualVMPath) { logUtils.logInfo('[visualvm] Selecting VisualVM installation'); const macOS = process.platform === 'darwin'; const selectedVisualVMUri = await vscode.window.showOpenDialog({ title: `${commands.COMMAND_SELECT_INSTALLATION_NAME} Folder`, canSelectFiles: macOS ? true : false, canSelectFolders: macOS ? false : true, canSelectMany: false, defaultUri: macOS ? vscode.Uri.file('/Applications') : savedVisualVMUri || vscode.Uri.file(os.homedir()), openLabel: process.platform === 'darwin' ? 'Select VisualVM Installation' : 'Select' }); if (selectedVisualVMUri?.length === 1) { visualVMPath = selectedVisualVMUri[0].fsPath; } else { logUtils.logInfo('[visualvm] VisualVM installation selection canceled'); } } if (visualVMPath) { const selectedVisualVMPath = visualVMPath; if (selectedVisualVMPath !== savedVisualVMPath) { logUtils.logInfo('[visualvm] Selected new VisualVM installation, saving installation path'); interactiveChange = true; await vscode.workspace.getConfiguration().update(INSTALLATION_PATH_KEY, selectedVisualVMPath, vscode.ConfigurationTarget.Global); } else { // Has to be handled separately, wouldn't trigger any notification from settings.json logUtils.logInfo('[visualvm] Selected current VisualVM installation, re-resolving'); resolve(true); } } } export async function get(interactive: boolean = false): Promise { const savedVisualVMPath = vscode.workspace.getConfiguration().get(INSTALLATION_PATH_KEY); if (savedVisualVMPath) { logUtils.logInfo(`[visualvm] Found defined installation path: ${savedVisualVMPath}`); return forPath(savedVisualVMPath, interactive); } else { logUtils.logInfo('[visualvm] No installation path defined'); return undefined; } } async function resolve(interactive: boolean = false) { logUtils.logInfo('[visualvm] Searching for VisualVM installation'); await vscode.commands.executeCommand('setContext', NO_INSTALLATION_KEY, false); await vscode.commands.executeCommand('setContext', INITIALIZED_KEY, false); view.hideNodes(); let installation = undefined; try { installation = await get(interactive); } finally { await vscode.commands.executeCommand('setContext', INITIALIZED_KEY, true); await vscode.commands.executeCommand('setContext', NO_INSTALLATION_KEY, !installation); if (installation) { view.showNodes(); } } } async function forPath(visualVMPath: string, interactive: boolean = false): Promise { if (!fs.existsSync(visualVMPath)) { logUtils.logError(`[visualvm] Installation path does not exist: ${visualVMPath}`); if (interactive) { vscode.window.showErrorMessage(`VisualVM installation path does not exist: ${visualVMPath}`); } return undefined; } if (!fs.statSync(visualVMPath).isDirectory()) { logUtils.logError(`[visualvm] Installation path is not a directory: ${visualVMPath}`); if (interactive) { vscode.window.showErrorMessage(`VisualVM installation path is not a directory: ${visualVMPath}`); } return undefined; } let isGraalVM: boolean = false; let isMacOsApp: boolean = false; const gvisualVMExecutable = path.join(visualVMPath, 'bin', process.platform === 'win32' ? 'visualvm.exe' : 'visualvm'); // GitHub VisualVM const mvisualVMExecutable = process.platform === 'darwin' && visualVMPath.endsWith('.app') ? path.join(visualVMPath, 'Contents', 'MacOS', 'visualvm') : undefined; // VisualVM.app on macOS const jvisualVMExecutable = path.join(visualVMPath, 'bin', process.platform === 'win32' ? 'jvisualvm.exe' : 'jvisualvm'); // GraalVM VisualVM if (!fs.existsSync(gvisualVMExecutable)) { if (!mvisualVMExecutable || !fs.existsSync(mvisualVMExecutable)) { if (!fs.existsSync(jvisualVMExecutable)) { logUtils.logError(`[visualvm] Installation executable does not exist: ${gvisualVMExecutable}`); if (interactive) { vscode.window.showErrorMessage(`VisualVM executable does not exist: ${gvisualVMExecutable}`); } return undefined; } else { logUtils.logInfo(`[visualvm] VisualVM executable found in GraalVM installation: ${mvisualVMExecutable}`); isGraalVM = true; } } else { logUtils.logInfo(`[visualvm] VisualVM executable found in MacOS application: ${mvisualVMExecutable}`); isMacOsApp = true; } } else { logUtils.logInfo(`[visualvm] VisualVM executable found in standard installation: ${gvisualVMExecutable}`); } const visualVMExecutable = isGraalVM ? jvisualVMExecutable : (isMacOsApp ? mvisualVMExecutable as string : gvisualVMExecutable); if (!fs.statSync(visualVMExecutable).isFile()) { logUtils.logError(`[visualvm] Installation executable is not a file: ${visualVMExecutable}`); if (interactive) { vscode.window.showErrorMessage(`Invalid VisualVM executable: ${visualVMExecutable}`); } return undefined; } logUtils.logInfo(`[visualvm] Found valid executable: ${visualVMExecutable}`); const visualVMGoToSourceJarPath = []; if (isGraalVM) visualVMGoToSourceJarPath.push(...[ 'lib', 'visualvm' ]); else if (isMacOsApp) visualVMGoToSourceJarPath.push(...[ 'Contents', 'Resources', 'visualvm' ]); visualVMGoToSourceJarPath.push(...[ 'visualvm', 'modules', 'org-graalvm-visualvm-gotosource.jar' ]); const visualVMGoToSourceJar = path.join(visualVMPath, ...visualVMGoToSourceJarPath); if (!fs.existsSync(visualVMGoToSourceJar)) { logUtils.logError(`[visualvm] Installation org-graalvm-visualvm-gotosource.jar does not exist: ${visualVMGoToSourceJar}`); if (interactive) { vscode.window.showErrorMessage(`Unsupported VisualVM version found in ${visualVMPath}. Please install the latest VisualVM from [${VISUALVM_HOMEPAGE}](${VISUALVM_HOMEPAGE}).`); } return undefined; } if (!fs.statSync(visualVMGoToSourceJar).isFile()) { logUtils.logError(`[visualvm] Installation org-graalvm-visualvm-gotosource.jar is not a file: ${visualVMGoToSourceJar}`); if (interactive) { vscode.window.showErrorMessage(`The selected VisualVM installation is broken: ${visualVMPath}`); } return undefined; } logUtils.logInfo(`[visualvm] Found valid org-graalvm-visualvm-gotosource.jar: ${visualVMGoToSourceJar}`); return { executable: visualVMExecutable, isGraalVM: isGraalVM, featureSet: 1 }; } export async function show(pid?: number, folder?: vscode.WorkspaceFolder): Promise { return vscode.window.withProgress({ location: { viewId: view.getViewId() } }, async () => { let params = parameters.windowToFront(); if (pid !== undefined) { params += ` ${parameters.openPid(pid)}`; } return invoke(params, folder); } ); } export async function perform(params: string | Promise, folder?: vscode.WorkspaceFolder): Promise { return vscode.window.withProgress({ location: { viewId: view.getViewId() } }, async () => { // Resolve provided params promise if (typeof params !== 'string') { logUtils.logInfo('[visualvm] Resolving provided parameters...'); const resolvedParams = await Promise.resolve(params); if (resolvedParams === undefined) { logUtils.logInfo('[visualvm] Canceled starting VisualVM'); return false; } else { params = resolvedParams; } } const windowToFront = parameters.windowToFrontConditional(); if (windowToFront) { params += ` ${windowToFront}`; } return invoke(params, folder); } ); } export async function invoke(params?: string, folder?: vscode.WorkspaceFolder, predefinedJDK?: string): Promise { logUtils.logInfo('[visualvm] Starting VisualVM'); const installation = await get(); if (!installation) { resolve(true); return false; } const command: string[] = []; // VisualVM executable ----- command.push(parameters.executable(installation.executable)); // Required parameters ----- // Increase commandline length for jvmstat command.push(parameters.perfMaxStringConstLength()); // Configurable pararameters // --jdkhome if (!installation.isGraalVM) { try { const jdkHome = await parameters.jdkHome(predefinedJDK); if (jdkHome) { command.push(jdkHome); } } catch (err) { logUtils.logError('[visualvm] Cannot start with --jdkhome, no JDK available'); return false; } } // User-defined parameters const userParams = parameters.userDefinedParameters(); if (userParams) { command.push(userParams); } // Go to Source integration const goToSource = await parameters.goToSource(folder); if (goToSource) { command.push(goToSource); } // Provided parameters ----- if (params) { command.push(params); } const commandString = command.join(' '); logUtils.logInfo(`[visualvm] Command: ${commandString}`); cp.exec(commandString); return true; } ================================================ FILE: integrations/vscode/src/vscodeUtils.ts ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import * as fs from 'fs'; import * as path from 'path'; import * as process from 'process'; export function findLauncher(): string | undefined { const execPath = process.execPath; let launcherPath: string | undefined = undefined; if (process.platform === 'darwin') { const CONTENTS_HANDLE = '/Contents'; const idx = execPath.indexOf(`${CONTENTS_HANDLE}/Frameworks/`); if (idx > -1) { launcherPath = `${execPath.substring(0, idx + CONTENTS_HANDLE.length)}/Resources/app/bin/code`; } } else { const execDir = path.resolve(execPath, '..'); launcherPath = path.join(execDir, 'bin', 'code'); if (process.platform === 'win32') { launcherPath = `${launcherPath}.cmd`; } } if (launcherPath && fs.existsSync(launcherPath)) { if (launcherPath.indexOf(' ') > -1) { launcherPath = `"${launcherPath}"`; } return launcherPath; } return undefined; } ================================================ FILE: integrations/vscode/tsconfig.eslint.json ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ { "extends": "./tsconfig.json", "include": [ ".eslintrc.js", "**/*.ts", "webpack.config.js" ] } ================================================ FILE: integrations/vscode/tsconfig.json ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ { "compilerOptions": { "allowJs": true, "module": "commonjs", "target": "es6", "outDir": "dist", "lib": [ "es6", "DOM" ], "sourceMap": true, "rootDir": "src", /* Strict Type-Checking Option */ "strict": true, /* enable all strict type-checking options */ /* Additional Checks */ "noUnusedLocals": true, /* Report errors on unused locals. */ "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ "noUnusedParameters": true, /* Report errors on unused parameters. */ "baseUrl": ".", "paths": { "vscode": [ "node_modules/@types/vscode" ] } }, "include": [ "src/**/*" ], "exclude": [ "node_modules", ".vscode-test" ] } ================================================ FILE: integrations/vscode/webpack.config.js ================================================ /* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ //@ts-check /* eslint-disable @typescript-eslint/naming-convention */ 'use strict'; const path = require('path'); const webpack = require('webpack'); const ESLintPlugin = require('eslint-webpack-plugin'); /**@type {import('webpack').Configuration}*/ const config = { target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ entry: { extension: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ }, output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ path: path.resolve(__dirname, 'dist'), filename: '[name].js', libraryTarget: "commonjs2", devtoolModuleFilenameTemplate: "../[resource-path]", }, devtool: 'source-map', externals: { vscode: "commonjs2 vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ }, resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader extensions: ['.ts', '.js', '.json'], modules: ['node_modules'], mainFields: ['main', 'module'], byDependency: { 'node-fetch': { mainFields: ['main', 'module'] }, 'isomorphic-fetch': { mainFields: ['main', 'module'] } } }, module: { rules: [{ test: /\.ts$/, exclude: /node_modules/, include: path.resolve(__dirname, 'src'), use: [{ loader: 'ts-loader' }] }] }, plugins: [ new ESLintPlugin({extensions: ['ts']}) ] }; const devConf = { target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ entry: { extension: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ }, output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ path: path.resolve(__dirname, 'dist'), filename: '[name].js', libraryTarget: "commonjs2", devtoolModuleFilenameTemplate: "../[resource-path]", }, devtool: 'source-map', externals: { vscode: "commonjs2 vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ }, resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader extensions: ['.ts', '.js', '.json'], modules: ['node_modules'], mainFields: ['main', 'module'], byDependency: { 'node-fetch': { mainFields: ['main', 'module'] }, 'isomorphic-fetch': { mainFields: ['main', 'module'] } }, symlinks: false, cacheWithContext: false, }, module: { rules: [{ test: /\.ts$/, exclude: /node_modules/, include: path.resolve(__dirname, 'src'), use: [{ loader: 'ts-loader', options: { transpileOnly: true, // https://github.com/TypeStrong/ts-loader#faster-builds } }] }] }, optimization: { minimize: false }, plugins: [ new webpack.AutomaticPrefetchPlugin() ], cache: { type: 'filesystem', buildDependencies: { // This makes all dependencies of this file - build dependencies config: [__filename], // By default webpack and loaders are build dependencies }, }, }; // https://webpack.js.org/configuration/mode/#mode-none module.exports = (env, argv) => { if (argv.mode === 'development') { return devConf; } if (argv.mode === 'production') { return config; } return config; }; ================================================ FILE: plugins/btrace/PROJECT_MOVED.txt ================================================ https://btrace.dev.java.net/source/browse/btrace/extra/visualvm-plugin-suite/ ================================================ FILE: plugins/buffermonitor/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.buffermonitor. ================================================ FILE: plugins/buffermonitor/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.modules.buffermonitor/2 OpenIDE-Module-Install: org/graalvm/visualvm/modules/buffermonitor/Installer.class OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/buffermonitor/Bundle.properties OpenIDE-Module-Specification-Version: 2.0 ================================================ FILE: plugins/buffermonitor/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/buffermonitor/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=81664b27 build.xml.script.CRC32=dcc223e1 build.xml.stylesheet.CRC32=05353c81 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=7dd7675e nbproject/build-impl.xml.script.CRC32=d3d069fa nbproject/build-impl.xml.stylesheet.CRC32=deb65f65 ================================================ FILE: plugins/buffermonitor/nbproject/project.properties ================================================ # # Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. javac.source=1.5 javac.compilerargs=-Xlint -Xlint:-serial license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Tomas Hurka, Jiri Sedlacek cp.extra=${tools.jar} module.javadoc.packages=org.graalvm.visualvm.modules.buffermonitor.* ================================================ FILE: plugins/buffermonitor/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.buffermonitor org.graalvm.visualvm.application 2 2.0 org.graalvm.visualvm.charts 2 2.0 org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.tools 2 2.0 org.openide.modules 7.3.1 org.openide.util 9.8 org.openide.util.ui 9.8 ================================================ FILE: plugins/buffermonitor/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/buffermonitor/src/org/graalvm/visualvm/modules/buffermonitor/BufferMonitorView.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.buffermonitor; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.charts.ChartFactory; import org.graalvm.visualvm.charts.SimpleXYChartDescriptor; import org.graalvm.visualvm.charts.SimpleXYChartSupport; import org.graalvm.visualvm.core.datasupport.DataRemovedListener; import org.graalvm.visualvm.core.options.GlobalPreferences; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Iterator; import java.util.List; import java.util.logging.Logger; import javax.management.Attribute; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.swing.Timer; import javax.swing.ImageIcon; import javax.swing.JPanel; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; /** * @author Tomas Hurka */ class BufferMonitorView extends DataSourceView implements DataRemovedListener { private static final String IMAGE_PATH = "org/graalvm/visualvm/modules/buffermonitor/resources/monitor.png"; // NOI18N private static final Logger LOGGER = Logger.getLogger(BufferMonitorView.class.getName()); private Timer timer; private Application application; private boolean refreshRunning; public BufferMonitorView(Application application) { super(application, NbBundle.getMessage(BufferMonitorView.class, "Buffer_Pools"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false); // NOI18N this.application = application; } @Override protected void removed() { timer.stop(); } protected DataViewComponent createComponent() { DataViewComponent dvc = new DataViewComponent( new MasterViewSupport(application).getMasterView(), new DataViewComponent.MasterViewConfiguration(false)); JmxModel jmx = JmxModelFactory.getJmxModelFor(application); String title = NbBundle.getMessage(BufferMonitorView.class, "LBL_DIRECT"); // NOI18N final BufferMonitorViewSupport directBufferViewSupport = new BufferMonitorViewSupport(jmx, title, BufferMonitorViewProvider.DIRECT_BUFFER_NAME); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(title, true), DataViewComponent.TOP_LEFT); dvc.addDetailsView(directBufferViewSupport.getDetailsView(), DataViewComponent.TOP_LEFT); title = NbBundle.getMessage(BufferMonitorView.class, "LBL_MAPPED"); // NOI18N final BufferMonitorViewSupport mappedBufferViewSupport = new BufferMonitorViewSupport(jmx, title, BufferMonitorViewProvider.MAPPED_BUFFER_NAME); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(title, true), DataViewComponent.TOP_RIGHT); dvc.addDetailsView(mappedBufferViewSupport.getDetailsView(), DataViewComponent.TOP_RIGHT); timer = new Timer(GlobalPreferences.sharedInstance().getMonitoredDataPoll() * 1000, new ActionListener() { public void actionPerformed(ActionEvent e) { if (refreshRunning) { return; } refreshRunning = true; RequestProcessor.getDefault().post(new Runnable() { public void run() { try { if (application.getState() == Application.STATE_AVAILABLE) { final long time = System.currentTimeMillis(); directBufferViewSupport.refresh(time); mappedBufferViewSupport.refresh(time); } } catch (Exception ex) { LOGGER.throwing(BufferMonitorView.class.getName(), "refresh", ex); // NOI18N } finally { refreshRunning = false; } } }); } }); timer.setInitialDelay(800); timer.start(); getDataSource().notifyWhenRemoved(this); return dvc; } public void dataRemoved(Application app) { timer.stop(); } private static class MasterViewSupport extends JPanel { public MasterViewSupport(Application app) { initComponents(app); } public DataViewComponent.MasterView getMasterView() { return new DataViewComponent.MasterView(NbBundle.getMessage(BufferMonitorView.class, "Buffer_Pools"), null, this); // NOI18N } private void initComponents(Application app) { setLayout(new BorderLayout()); setOpaque(false); } String getGeneralInfo(Application app) { return ""; } } private static class BufferMonitorViewSupport extends JPanel { private static final String MEMORY_USED = NbBundle.getMessage(BufferMonitorView.class, "LBL_Memory_Used"); // NOI18N private static final String TOTAL_CAPACITY = NbBundle.getMessage(BufferMonitorView.class, "LBL_Total_Capacity"); // NOI18N private static final String COUNT = NbBundle.getMessage(BufferMonitorView.class, "LBL_Count"); // NOI18N private SimpleXYChartSupport chartSupport; private final String TITLE; private ObjectName bufferObjectName; private final MBeanServerConnection conn; private final String[] attributes = {"Count","MemoryUsed","TotalCapacity"}; // NOI18N public BufferMonitorViewSupport(JmxModel jmx, String title, String bufferName) { GlobalPreferences preferences = GlobalPreferences.sharedInstance(); int chartCache = preferences.getMonitoredDataCache() * 60 / preferences.getMonitoredDataPoll(); conn = jmx.getMBeanServerConnection(); try { bufferObjectName = new ObjectName(bufferName); } catch (MalformedObjectNameException ex) { ex.printStackTrace(); } TITLE = title; initModels(chartCache); initComponents(); } public DataViewComponent.DetailsView getDetailsView() { return new DataViewComponent.DetailsView(TITLE, null, 10, this, null); } public void refresh(long time) { long count = 0; long memoryUsed = 0; long totalCapacity = 0; List attrs; try { attrs = conn.getAttributes(bufferObjectName, attributes); } catch (Exception ex) { ex.printStackTrace(); return; } Iterator attrIt = attrs.iterator(); while(attrIt.hasNext()) { Attribute attrib = (Attribute) attrIt.next(); String name = attrib.getName(); if (attributes[0].equals(name)) { count = ((Long)attrib.getValue()).longValue(); } else if (attributes[1].equals(name)) { memoryUsed = ((Long)attrib.getValue()).longValue(); } else if (attributes[2].equals(name)) { totalCapacity = ((Long)attrib.getValue()).longValue(); } } chartSupport.addValues(time, new long[] { memoryUsed, totalCapacity }); chartSupport.updateDetails(new String[] { chartSupport.formatBytes(memoryUsed), chartSupport.formatBytes(totalCapacity), chartSupport.formatDecimal(count)}); } private void initModels(int chartCache) { SimpleXYChartDescriptor chartDescriptor = SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, chartCache); chartDescriptor.addLineFillItems(MEMORY_USED, TOTAL_CAPACITY); chartDescriptor.setDetailsItems(new String[] { MEMORY_USED, TOTAL_CAPACITY, COUNT }); chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor); } private void initComponents() { setLayout(new BorderLayout()); setOpaque(false); add(chartSupport.getChart(), BorderLayout.CENTER); } } } ================================================ FILE: plugins/buffermonitor/src/org/graalvm/visualvm/modules/buffermonitor/BufferMonitorViewProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.buffermonitor; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.DataSourceViewProvider; import org.graalvm.visualvm.core.ui.DataSourceViewsManager; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import java.io.IOException; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; /** * * @author Tomas Hurka */ public class BufferMonitorViewProvider extends DataSourceViewProvider { static final String DIRECT_BUFFER_NAME = "java.nio:type=BufferPool,name=direct"; static final String MAPPED_BUFFER_NAME = "java.nio:type=BufferPool,name=mapped"; protected boolean supportsViewFor(Application application) { JmxModel jmx = JmxModelFactory.getJmxModelFor(application); if (jmx != null && jmx.getConnectionState() == JmxModel.ConnectionState.CONNECTED) { MBeanServerConnection connection = jmx.getMBeanServerConnection(); try { if (connection.isRegistered(new ObjectName(DIRECT_BUFFER_NAME))) { return true; } } catch (MalformedObjectNameException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } } return false; } protected DataSourceView createView(Application application) { return new BufferMonitorView(application); } public void initialize() { DataSourceViewsManager.sharedInstance().addViewProvider(this, Application.class); } } ================================================ FILE: plugins/buffermonitor/src/org/graalvm/visualvm/modules/buffermonitor/Bundle.properties ================================================ # # Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Tools OpenIDE-Module-Long-Description=\ A plugin to monitor usage of direct buffers created by ByteBuffer.allocateDirect and mapped buffers created by FileChannel.map. \ Note that the buffers monitoring requires the monitored application to run JDK 7 starting from Build 36. OpenIDE-Module-Name=VisualVM-BufferMonitor OpenIDE-Module-Short-Description=VisualVM Buffer Pools Monitor Buffer_Pools=Buffer Pools LBL_DIRECT=Direct LBL_MAPPED=Mapped LBL_Memory_Used=Memory Used LBL_Total_Capacity=Total Capacity LBL_Count=Count ================================================ FILE: plugins/buffermonitor/src/org/graalvm/visualvm/modules/buffermonitor/Installer.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.buffermonitor; import org.openide.modules.ModuleInstall; /** * Manages a module's lifecycle. */ public class Installer extends ModuleInstall { @Override public void restored() { new BufferMonitorViewProvider().initialize(); } } ================================================ FILE: plugins/build.xml ================================================ Builds the module suite plugins. ================================================ FILE: plugins/consumerentrypoints/build.xml ================================================ Builds, tests, and runs the project org.netbeans.modules.consumerentrypoints. ================================================ FILE: plugins/consumerentrypoints/manifest.mf ================================================ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: true OpenIDE-Module: org.netbeans.modules.consumerentrypoints OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/consumerentrypoints/resources/Bundle.properties OpenIDE-Module-Specification-Version: 1.0 OpenIDE-Module-Layer: org/netbeans/modules/consumerentrypoints/resources/layer.xml ================================================ FILE: plugins/consumerentrypoints/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/consumerentrypoints/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=8d071d57 build.xml.script.CRC32=8d2ba218 build.xml.stylesheet.CRC32=79c3b980 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=8d071d57 nbproject/build-impl.xml.script.CRC32=20b8525a nbproject/build-impl.xml.stylesheet.CRC32=deb65f65 ================================================ FILE: plugins/consumerentrypoints/nbproject/project.properties ================================================ javac.source=1.5 javac.compilerargs=-Xlint -Xlint:-serial nbm.module.author=Jirka Rechtacek ================================================ FILE: plugins/consumerentrypoints/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.netbeans.modules.consumerentrypoints org.netbeans.modules.consumervisualvm 1.0 ================================================ FILE: plugins/consumerentrypoints/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/consumerentrypoints/src/org/netbeans/modules/consumerentrypoints/resources/Bundle.properties ================================================ OpenIDE-Module-Display-Category=Infrastructure OpenIDE-Module-Name=Consumer VisualVM OpenIDE-Module-Short-Description=Entry Points to Consumer Visual VM API org-netbeans-modules-consumerentrypoints-GlassFishApplicationTypeAction=Enable GlassFish Plugin ================================================ FILE: plugins/consumerentrypoints/src/org/netbeans/modules/consumerentrypoints/resources/glassfish.xml ================================================ ================================================ FILE: plugins/consumerentrypoints/src/org/netbeans/modules/consumerentrypoints/resources/layer.xml ================================================ ================================================ FILE: plugins/consumervisualvm/build.xml ================================================ Builds, tests, and runs the project org.netbeans.modules.consumervisualvm. ================================================ FILE: plugins/consumervisualvm/manifest.mf ================================================ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: false OpenIDE-Module: org.netbeans.modules.consumervisualvm OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/consumervisualvm/resources/Bundle.properties OpenIDE-Module-Specification-Version: 1.0 ================================================ FILE: plugins/consumervisualvm/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/consumervisualvm/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=5e183de4 build.xml.script.CRC32=96930916 build.xml.stylesheet.CRC32=79c3b980 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=5e183de4 nbproject/build-impl.xml.script.CRC32=eddd2eb4 nbproject/build-impl.xml.stylesheet.CRC32=deb65f65 ================================================ FILE: plugins/consumervisualvm/nbproject/project.properties ================================================ is.autoload=true javac.source=1.5 javac.compilerargs=-Xlint -Xlint:-serial nbm.module.author=Jirka Rechtacek ================================================ FILE: plugins/consumervisualvm/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.netbeans.modules.consumervisualvm org.graalvm.visualvm.application 0-1 1.0 org.graalvm.visualvm.core 0-1 1.0 org.netbeans.api.progress 1 1.10.1.1 org.netbeans.modules.autoupdate.services 1.3.1 org.openide.awt 6.11.1.1 org.openide.dialogs 7.5.1 org.openide.filesystems 7.3.1 org.openide.modules 7.3.1 org.openide.util 8.6.1 org.netbeans.modules.consumervisualvm.api ================================================ FILE: plugins/consumervisualvm/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/consumervisualvm/src/META-INF/services/org.openide.filesystems.FileSystem ================================================ org.netbeans.modules.consumervisualvm.DecoratedFileSystem ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/DecoratedFileSystem.java ================================================ /* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.netbeans.modules.consumervisualvm; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.netbeans.modules.consumervisualvm.PluginInfoAccessor.Internal; import org.netbeans.modules.consumervisualvm.api.PluginInfo; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileSystem; import org.openide.filesystems.MultiFileSystem; import org.openide.filesystems.XMLFileSystem; import org.openide.util.Lookup; import org.openide.util.RequestProcessor; import org.openide.util.lookup.Lookups; /** * * @author Jirka Rechtacek */ public class DecoratedFileSystem extends MultiFileSystem implements Runnable { final static Logger LOG = Logger.getLogger (DecoratedFileSystem.class.getPackage ().toString ()); private static RequestProcessor RP = new RequestProcessor ("ConsumerVisualVM"); // NOI18N private static Lookup consumerVisualVM; public DecoratedFileSystem () { RP.post (this, 2000); //SwingUtilities.invokeLater (this); } public void run () { Lookup l = consumerVisualVM (); try { Class.forName ("org.netbeans.modules.consumervisualvm.api.PluginInfo"); } catch (ClassNotFoundException ex) { // XXX: why ClassNotFoundException sometime? LOG.log (Level.FINE, ex.getLocalizedMessage (), ex); return; } Lookup.Result result = l.lookupResult (PluginInfo.class); List delegate = new ArrayList (); for (PluginInfo pi : result.allInstances ()) { Internal internal = PluginInfoAccessor.DEFAULT.getInternal (pi); if (! internal.isEnabled ()) { delegate.add (internal.getXMLFileSystem ()); } } setDelegates (delegate.toArray (new FileSystem[0])); } public static DecoratedFileSystem getInstance () { return Lookup.getDefault ().lookup (DecoratedFileSystem.class); } public void refresh () { RP.post (this).waitFinished (); } public URL getParentFileSystem (FileObject template) { Lookup.Result result = consumerVisualVM ().lookupResult (PluginInfo.class); String path = template.getPath (); for (PluginInfo pi : result.allInstances ()) { Internal internal = PluginInfoAccessor.DEFAULT.getInternal (pi); XMLFileSystem fs = internal.getXMLFileSystem (); if (fs.findResource (path) != null) { return fs.getXmlUrl (); } } return null; } public String getPluginCodeName (FileObject template) { Lookup.Result result = consumerVisualVM ().lookupResult (PluginInfo.class); String path = template.getPath (); for (PluginInfo pi : result.allInstances ()) { Internal internal = PluginInfoAccessor.DEFAULT.getInternal (pi); XMLFileSystem fs = internal.getXMLFileSystem (); if (fs.findResource (path) != null) { return PluginInfoAccessor.DEFAULT.getCodeName (pi); } } return null; } private static synchronized Lookup consumerVisualVM () { if (consumerVisualVM != null) { return consumerVisualVM; } return consumerVisualVM = Lookups.forPath ("ConsumerVisualVM"); // NOI18N } } ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/PluginInfoAccessor.java ================================================ /* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.netbeans.modules.consumervisualvm; import java.beans.PropertyVetoException; import java.io.IOException; import java.net.URL; import java.util.logging.Level; import org.netbeans.modules.consumervisualvm.api.PluginInfo; import org.openide.filesystems.XMLFileSystem; import org.openide.modules.ModuleInfo; import org.openide.util.Exceptions; import org.openide.util.Lookup; /** Accessor for non-public methods of FeatureInfo * * @author Jaroslav Tulach */ public abstract class PluginInfoAccessor { public static PluginInfoAccessor DEFAULT; protected PluginInfoAccessor () { assert DEFAULT == null; DEFAULT = this; } public abstract String getCodeName (PluginInfo info); public abstract URL getPluginLayer (PluginInfo info); public abstract Internal getInternal (PluginInfo info); /** Instance associated with each FeatureInfo, which can hold the * internal data needed for it */ public static final class Internal { private final PluginInfo info; private XMLFileSystem fs; public Internal (PluginInfo info) { this.info = info; } synchronized XMLFileSystem getXMLFileSystem () { if (fs == null) { URL url = DEFAULT.getPluginLayer (info); fs = new XMLFileSystem (); if (url != null) { try { fs.setXmlUrl (url); } catch (IOException ex) { DecoratedFileSystem.LOG.log (Level.SEVERE, "Cannot parse: " + url, ex); Exceptions.printStackTrace (ex); } catch (PropertyVetoException ex) { DecoratedFileSystem.LOG.log (Level.SEVERE, "Cannot parse: " + url, ex); Exceptions.printStackTrace (ex); } } } return fs; } boolean isEnabled () { String cnb = DEFAULT.getCodeName (info); for (ModuleInfo mi : Lookup.getDefault ().lookupAll (ModuleInfo.class)) { if (cnb.equals (mi.getCodeNameBase ())) { return mi.isEnabled (); } } return false; } } } ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/api/ApplicationTypeAction.java ================================================ /* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.netbeans.modules.consumervisualvm.api; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.application.jvm.JvmFactory; import org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction; import java.awt.event.ActionEvent; import java.util.Collection; import java.util.ResourceBundle; import java.util.Set; import org.netbeans.api.autoupdate.UpdateElement; import org.netbeans.modules.consumervisualvm.DecoratedFileSystem; import org.netbeans.modules.consumervisualvm.engine.FindComponentModules; import org.netbeans.modules.consumervisualvm.engine.ModulesActivator; import org.netbeans.modules.consumervisualvm.engine.ModulesInstaller; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.filesystems.FileObject; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; /** * * @author Jirka Rechtacek */ public class ApplicationTypeAction extends MultiDataSourceAction { public static final String MAIN_CLASS_NAME = "mainClassName"; public static final String PLUGIN_CODE_NAME = "pluginCodeName"; public static final String ACTION_NAME = "ActionName"; public static final String LOCALIZING_BUNDLE = "SystemFileSystem.localizingBundle"; private String mainClassName; private String pluginCodeName; private String displayName; public static synchronized ApplicationTypeAction newAction (FileObject fo) { return new ApplicationTypeAction (fo); } private ApplicationTypeAction (FileObject fo) { super (Application.class); mainClassName = (String) fo.getAttribute (MAIN_CLASS_NAME); pluginCodeName = (String) fo.getAttribute (PLUGIN_CODE_NAME); String bundle = (String) fo.getAttribute (LOCALIZING_BUNDLE); ResourceBundle b = NbBundle.getBundle (bundle); displayName = b.getString ((String) fo.getAttribute (ACTION_NAME)); putValue(NAME, displayName); } protected void actionPerformed (Set arg0, ActionEvent arg1) { RequestProcessor.getDefault ().post (new Runnable () { public void run () { FindComponentModules findModules = new FindComponentModules (pluginCodeName); findModules.createFindingTask ().waitFinished (); Collection toInstall = findModules.getModulesForInstall (); Collection toEnable = findModules.getModulesForEnable (); if (toInstall != null && ! toInstall.isEmpty ()) { ModulesInstaller installer = new ModulesInstaller (toInstall); installer.getInstallTask ().waitFinished (); DecoratedFileSystem.getInstance ().refresh (); } else if (toEnable != null && ! toEnable.isEmpty ()) { ModulesActivator enabler = new ModulesActivator (toEnable); enabler.getEnableTask ().waitFinished (); DecoratedFileSystem.getInstance ().refresh (); } else { DialogDisplayer.getDefault ().notifyLater (new NotifyDescriptor.Message ( NbBundle.getMessage (ApplicationTypeAction.class, "ApplicationTypeAction_ProblemDescription", findModules.getProblemDescription ()))); } } }); } protected boolean isEnabled (Set sources) { if (sources == null || sources.isEmpty ()) { return false; } for (Application app : sources) { Jvm jvm = JvmFactory.getJVMFor (app); if (mainClassName.equals (jvm.getMainClass ())) { return true; } } return false; } } ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/api/Bundle.properties ================================================ # Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. ApplicationTypeAction_ProblemDescription={0} Check your Update Centers in Tools|Plugins and try it later. ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/api/PluginInfo.java ================================================ /* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.netbeans.modules.consumervisualvm.api; import java.net.URL; import org.netbeans.modules.consumervisualvm.PluginInfoAccessor; import org.netbeans.modules.consumervisualvm.PluginInfoAccessor.Internal; import org.openide.filesystems.FileObject; /** * * @author Jaroslav Tulach */ public final class PluginInfo { private final String codeName; private final URL pluginLayer; private Internal internal = new Internal (this); private PluginInfo (String codeName, URL pluginLayer) { this.codeName = codeName; this.pluginLayer = pluginLayer; } private static PluginInfo create (String codeName, URL pluginLayer) { return new PluginInfo (codeName, pluginLayer); } static PluginInfo create (FileObject fo) { Object cnb = fo.getAttribute ("codeName"); // NOI18N Object layer = fo.getAttribute ("delegateLayer"); // NOI18N return create ((String) cnb, (URL) layer); } static { PluginInfoAccessor.DEFAULT = new PluginInfoAccessor () { @Override public String getCodeName (PluginInfo info) { return info.codeName; } @Override public URL getPluginLayer (PluginInfo info) { return info.pluginLayer; } @Override public Internal getInternal (PluginInfo info) { return info.internal; } }; } } ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/Bundle.properties ================================================ # Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. InstallerMissingModules_Download=Downloading {0} ModulesActivator_Enable=Activating {0} InstallerMissingModules_Verify=Verifing... InstallerMissingModules_Install=Installing... InstallerMissingModules_TryAgainButton=&Try Again InstallerMissingModules_ErrorPanel_Title=Error InstallerMissingModules_ErrorPanel=Installation cannot be completed due to {0} \n {1} InstallerMissingModules_NeedsRestart=Restart IDE to complete instaling asked plugins. FindComponentModules_Problem_PluginNotFound=The plugin {0} is not avialable in this moment. FindComponentModules_Problem_DependingPluginNotFound=The plugin {0} cannot satisfy all its dependencies {1}. Maybe some required plugins are not avialable in this moment. ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/FindComponentModules.java ================================================ /* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.netbeans.modules.consumervisualvm.engine; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import java.util.StringTokenizer; import java.util.prefs.Preferences; import javax.swing.SwingUtilities; import org.netbeans.api.autoupdate.InstallSupport; import org.netbeans.api.autoupdate.OperationContainer; import org.netbeans.api.autoupdate.OperationSupport; import org.netbeans.api.autoupdate.UpdateElement; import org.netbeans.api.autoupdate.UpdateManager; import org.netbeans.api.autoupdate.UpdateUnit; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; import org.openide.util.RequestProcessor; /** * * @author Jirka Rechtacek */ public final class FindComponentModules { private Collection codeNames; private String problemDescription; public FindComponentModules (String... components) { if (components == null) { codeNames = Collections.emptySet (); } else { codeNames = Arrays.asList (components); } } public final String DO_CHECK = "do-check"; private final String ENABLE_LATER = "enable-later"; private Collection forInstall = null; private Collection forEnable = null; private RequestProcessor.Task componentModulesFindingTask = null; private RequestProcessor.Task enableLaterTask = null; public RequestProcessor.Task getFindingTask () { return componentModulesFindingTask; } public RequestProcessor.Task createFindingTask () { assert componentModulesFindingTask == null || componentModulesFindingTask.isFinished () : "The Finding Task cannot be started nor scheduled."; componentModulesFindingTask = RequestProcessor.getDefault ().create (doFind); return componentModulesFindingTask; } public Collection getModulesForInstall () { assert forInstall != null : "candidates cannot be null if getModulesForInstall() is called."; return forInstall; } public String getProblemDescription () { return problemDescription; } public void clearModulesForInstall () { forInstall = null; componentModulesFindingTask = null; enableLaterTask = null; } public void writeEnableLater (Collection modules) { Preferences pref = FindComponentModules.getPreferences (); if (modules == null) { pref.remove (ENABLE_LATER); return ; } String value = ""; for (UpdateElement m : modules) { value += value.length () == 0 ? m.getCodeName () : ", " + m.getCodeName (); // NOI18N } if (value.trim ().length () == 0) { pref.remove (ENABLE_LATER); } else { pref.put (ENABLE_LATER, value); } } public Collection getModulesForEnable () { assert forEnable != null : "candidates cannot be null if getModulesForInstall() is called."; return forEnable; } private Collection readEnableLater () { Set res = new HashSet (); Preferences pref = FindComponentModules.getPreferences (); String value = pref.get (ENABLE_LATER, null); if (value != null && value.trim ().length () > 0) { Enumeration en = new StringTokenizer (value, ","); // NOI18N while (en.hasMoreElements ()) { String codeName = ((String) en.nextElement ()).trim (); UpdateElement el = findUpdateElement (codeName, true); if (el != null) { res.add (el); } } } return res; } public static Collection getVisibleUpdateElements (Collection elems) { Collection res = new HashSet (); for (UpdateElement el : new LinkedList (elems)) { if (UpdateManager.TYPE.KIT_MODULE.equals (el.getUpdateUnit ().getType ())) { res.add (el); } } return res; } public static Preferences getPreferences () { return NbPreferences.forModule (FindComponentModules.class); } private Runnable doFind = new Runnable () { public void run() { if (SwingUtilities.isEventDispatchThread ()) { RequestProcessor.getDefault ().post (doFind); return ; } findComponentModules (); } }; private void findComponentModules () { Collection units = UpdateManager.getDefault ().getUpdateUnits (UpdateManager.TYPE.MODULE); problemDescription = null; // install missing modules Collection elementsForInstall = getMissingModules (units); forInstall = getAllForInstall (elementsForInstall); // install disabled modules Collection elementsForEnable = getDisabledModules (units); forEnable = getAllForEnable (elementsForEnable); if (problemDescription == null && elementsForInstall.isEmpty () && elementsForEnable.isEmpty ()) { problemDescription = NbBundle.getMessage (FindComponentModules.class, "FindComponentModules_Problem_PluginNotFound", codeNames); } } private Collection getMissingModules (Collection allUnits) { Set res = new HashSet (); for (UpdateUnit unit : allUnits) { if (unit.getInstalled () == null && codeNames.contains(unit.getCodeName ())) { res.add (unit.getAvailableUpdates ().get (0)); } } return res; } private Collection getAllForInstall (Collection elements) { Collection all = new HashSet (); for (UpdateElement el : elements) { OperationContainer ocForInstall = OperationContainer.createForInstall (); if (ocForInstall.canBeAdded (el.getUpdateUnit (), el)) { OperationContainer.OperationInfo info = ocForInstall.add (el); if (info == null) { continue; } Set reqs = info.getRequiredElements (); ocForInstall.add (reqs); Set breaks = info.getBrokenDependencies (); if (breaks.isEmpty ()) { all.add (el); all.addAll (reqs); } else { problemDescription = NbBundle.getMessage (FindComponentModules.class, "FindComponentModules_Problem_DependingPluginNotFound", codeNames, breaks); } } } return all; } private Collection getDisabledModules (Collection allUnits) { Set res = new HashSet (); for (UpdateUnit unit : allUnits) { if (unit.getInstalled () != null && codeNames.contains(unit.getCodeName ())) { if (! unit.getInstalled ().isEnabled ()) { res.add (unit.getInstalled ()); } } } return res; } private Collection getAllForEnable (Collection elements) { Collection all = new HashSet (); for (UpdateElement el : elements) { OperationContainer ocForEnable = OperationContainer.createForEnable (); if (ocForEnable.canBeAdded (el.getUpdateUnit (), el)) { OperationContainer.OperationInfo info = ocForEnable.add (el); if (info == null) { continue; } Set reqs = info.getRequiredElements (); ocForEnable.add (reqs); Set breaks = info.getBrokenDependencies (); if (breaks.isEmpty ()) { all.add (el); all.addAll (reqs); } else { problemDescription = NbBundle.getMessage (FindComponentModules.class, "FindComponentModules_Problem_DependingPluginNotFound", codeNames, breaks); } } } return all; } private static UpdateElement findUpdateElement (String codeName, boolean isInstalled) { UpdateElement res = null; for (UpdateUnit u : UpdateManager.getDefault ().getUpdateUnits (UpdateManager.TYPE.MODULE)) { if (codeName.equals (u.getCodeName ())) { if (isInstalled && u.getInstalled () != null) { res = u.getInstalled (); } else if (! isInstalled && ! u.getAvailableUpdates ().isEmpty ()) { res = u.getAvailableUpdates ().get (0); } break; } } return res; } } ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/FlashingIcon.java ================================================ /* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.netbeans.modules.consumervisualvm.engine; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JToolTip; import org.openide.util.RequestProcessor; import org.openide.util.RequestProcessor.Task; // Copied from org.netbeans.core.FlashingIcon /** * * A flashing icon to provide visual feedback for the user when something * not very important happens in the system. * The icon is flashed for a few seconds and then remains visible for a while longer. * * @author saubrecht */ abstract class FlashingIcon extends JComponent implements MouseListener { protected int STOP_FLASHING_DELAY = 10 * 1000; protected int DISAPPEAR_DELAY_MILLIS = STOP_FLASHING_DELAY + 50 * 1000; protected int FLASHING_FREQUENCY = 500; private Icon icon; private boolean keepRunning = false; private boolean isIconVisible = false; private boolean keepFlashing = true; private long startTime = 0; private Task timerTask; /** * Creates a new instance of FlashingIcon * * @param icon The icon that will be flashing (blinking) */ protected FlashingIcon( Icon icon ) { this.icon = icon; Dimension d = new Dimension( icon.getIconWidth(), icon.getIconHeight() ); setMinimumSize( d ); setMaximumSize( d ); setPreferredSize( d ); setVisible (false); addMouseListener( this ); } /** * Start flashing of the icon. If the icon is already flashing, the timer * is reset. * If the icon is visible but not flashing, it starts flashing again * and the disappear timer is reset. */ public void startFlashing() { synchronized( this ) { startTime = System.currentTimeMillis(); isIconVisible = !isIconVisible; keepRunning = true; keepFlashing = true; if( null == timerTask ) { timerTask = RequestProcessor.getDefault ().post (new Timer ()); } else { timerTask.run (); } this.setVisible (true); } repaint(); } /** * Stop the flashing and hide the icon. */ public void disappear() { synchronized( this ) { keepRunning = false; isIconVisible = false; keepFlashing = false; if( null != timerTask ) timerTask.cancel(); timerTask = null; setToolTipText( null ); this.setVisible (false); } repaint(); } /** * Stop flashing of the icon. The icon remains visible and active (listens * for mouse clicks and displays tooltip) until the disappear timer expires. */ public void stopFlashing() { synchronized( this ) { if( keepRunning && !isIconVisible ) { isIconVisible = true; repaint(); } } keepFlashing = false; } /** * Switch the current image and repaint */ protected void flashIcon() { isIconVisible = !isIconVisible; repaint(); } @Override public void paint(java.awt.Graphics g) { if( isIconVisible ) { icon.paintIcon( this, g, 0, 0 ); } } public void mouseReleased(MouseEvent e) {} public void mousePressed(MouseEvent e) { stopFlashing(); } public void mouseExited(MouseEvent e) { stopFlashing(); } public void mouseEntered(MouseEvent e) { stopFlashing(); } public void mouseClicked(MouseEvent e) { if( isIconVisible ) { //disappear(); onMouseClick(); } } /** * Invoked when the user clicks the icon. */ protected abstract void onMouseClick(); /** * Invoked when the disappear timer expired. */ protected abstract void timeout(); @Override public Cursor getCursor() { if( isIconVisible ) { return Cursor.getPredefinedCursor( Cursor.HAND_CURSOR ); } return Cursor.getDefaultCursor(); } @Override public Point getToolTipLocation( MouseEvent event ) { JToolTip tip = createToolTip(); tip.setTipText( getToolTipText() ); Dimension d = tip.getPreferredSize(); Point retValue = new Point( getWidth()-d.width, -d.height ); return retValue; } private class Timer implements Runnable { public void run() { synchronized( FlashingIcon.this ) { long currentTime = System.currentTimeMillis(); if( keepFlashing ) { if( currentTime - startTime < STOP_FLASHING_DELAY ) { flashIcon(); } else { stopFlashing(); if (DISAPPEAR_DELAY_MILLIS == -1) { timerTask = null; } } } if( DISAPPEAR_DELAY_MILLIS > 0 && currentTime - startTime >= DISAPPEAR_DELAY_MILLIS ) { disappear(); timeout(); } else { if( null != timerTask ) timerTask.schedule( FLASHING_FREQUENCY ); } } } } } ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/ModulesActivator.java ================================================ /* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.netbeans.modules.consumervisualvm.engine; import java.util.Collection; import java.util.LinkedList; import javax.swing.SwingUtilities; import org.netbeans.api.autoupdate.OperationContainer; import org.netbeans.api.autoupdate.OperationException; import org.netbeans.api.autoupdate.OperationSupport; import org.netbeans.api.autoupdate.UpdateElement; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; /** * * @author Jirka Rechtacek */ public class ModulesActivator { private Collection modules4enable; private RequestProcessor.Task enableTask = null; private OperationContainer enableContainer; public ModulesActivator (Collection modules) { if (modules == null || modules.isEmpty ()) { throw new IllegalArgumentException ("Cannot construct ModulesActivator with null or empty Collection " + modules); } modules4enable = modules; } public RequestProcessor.Task getEnableTask () { if (enableTask == null) { enableTask = createEnableTask (); } return enableTask; } private RequestProcessor.Task createEnableTask () { assert enableTask == null || enableTask.isFinished () : "The Enable Task cannot be started nor scheduled."; enableTask = RequestProcessor.getDefault ().create (doEnable); return enableTask; } private Runnable doEnable = new Runnable () { public void run() { enableModules (); } }; private void enableModules () { try { doEnableModules (); } catch (Exception x) { Exceptions.printStackTrace (x); } } private void doEnableModules () throws OperationException { assert ! SwingUtilities.isEventDispatchThread () : "Cannot be called in EQ."; enableContainer = null; for (UpdateElement module : modules4enable) { if (enableContainer == null) { enableContainer = OperationContainer.createForEnable (); } if (enableContainer.canBeAdded (module.getUpdateUnit (), module)) { enableContainer.add (module); } } if (enableContainer.listAll ().isEmpty ()) { return ; } assert enableContainer.listInvalid ().isEmpty () : "No invalid Update Elements " + enableContainer.listInvalid (); if (! enableContainer.listInvalid ().isEmpty ()) { throw new IllegalArgumentException ("Some are invalid for enable: " + enableContainer.listInvalid ()); } OperationSupport enableSupport = enableContainer.getSupport (); ProgressHandle enableHandle = ProgressHandleFactory.createHandle ( getBundle ("ModulesActivator_Enable", presentUpdateElements (FindComponentModules.getVisibleUpdateElements (modules4enable)))); enableSupport.doOperation (enableHandle); } public static String presentUpdateElements (Collection elems) { String res = ""; for (UpdateElement el : new LinkedList (elems)) { res += res.length () == 0 ? el.getDisplayName () : ", " + el.getDisplayName (); // NOI18N } return res; } private static String getBundle (String key, Object... params) { return NbBundle.getMessage (ModulesActivator.class, key, params); } } ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/ModulesInstaller.java ================================================ /* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.netbeans.modules.consumervisualvm.engine; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Collection; import java.util.LinkedList; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JTextArea; import javax.swing.SwingUtilities; import org.netbeans.api.autoupdate.InstallSupport; import org.netbeans.api.autoupdate.InstallSupport.Installer; import org.netbeans.api.autoupdate.InstallSupport.Validator; import org.netbeans.api.autoupdate.OperationContainer; import org.netbeans.api.autoupdate.OperationException; import org.netbeans.api.autoupdate.OperationSupport.Restarter; import org.netbeans.api.autoupdate.UpdateElement; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; import org.netbeans.modules.consumervisualvm.engine.RestartNotifier.RestartIcon; import org.openide.DialogDisplayer; import org.openide.LifecycleManager; import org.openide.NotifyDescriptor; import org.openide.awt.Mnemonics; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; /** * * @author Jirka Rechtacek */ public class ModulesInstaller { private Collection modules4install; private RequestProcessor.Task installTask = null; private OperationContainer installContainer; public ModulesInstaller (Collection modules) { if (modules == null || modules.isEmpty ()) { throw new IllegalArgumentException ("Cannot construct InstallerMissingModules with null or empty Collection " + modules); } modules4install = modules; } public RequestProcessor.Task getInstallTask () { if (installTask == null) { installTask = createInstallTask (); } return installTask; } private RequestProcessor.Task createInstallTask () { assert installTask == null || installTask.isFinished () : "The Install Task cannot be started nor scheduled."; installTask = RequestProcessor.getDefault ().create (doInstall); return installTask; } private Runnable doInstall = new Runnable () { public void run() { installMissingModules (); } }; private void installMissingModules () { try { doInstallMissingModules (); } catch (Exception x) { JButton tryAgain = new JButton (); tryAgain.addActionListener(new ActionListener () { public void actionPerformed (ActionEvent e) { if (installContainer != null) { try { installContainer.getSupport ().doCancel (); } catch (Exception ex) { Logger.getLogger (ModulesInstaller.class.getName ()). log (Level.INFO, ex.getLocalizedMessage (), ex); } } RequestProcessor.Task task = getInstallTask (); if (task != null) { task.schedule (10); } } }); tryAgain.setEnabled (getInstallTask () != null); Mnemonics.setLocalizedText (tryAgain, getBundle ("InstallerMissingModules_TryAgainButton")); NotifyDescriptor nd = new NotifyDescriptor ( getErrorNotifyPanel (x), getBundle ("InstallerMissingModules_ErrorPanel_Title"), NotifyDescriptor.DEFAULT_OPTION, NotifyDescriptor.ERROR_MESSAGE, new Object [] { tryAgain, NotifyDescriptor.OK_OPTION }, NotifyDescriptor.OK_OPTION ); DialogDisplayer.getDefault ().notifyLater (nd); } } private JComponent getErrorNotifyPanel (Exception x) { JTextArea area = new JTextArea (); area.setWrapStyleWord (true); area.setLineWrap (true); area.setEditable (false); area.setRows (15); area.setColumns (40); area.setOpaque (false); area.setText (getBundle ("InstallerMissingModules_ErrorPanel", x.getLocalizedMessage (), x)); return area; } private void doInstallMissingModules () throws OperationException { assert ! SwingUtilities.isEventDispatchThread () : "Cannot be called in EQ."; installContainer = null; for (UpdateElement module : modules4install) { if (installContainer == null) { boolean isNewOne = module.getUpdateUnit ().getInstalled () == null; if (isNewOne) { installContainer = OperationContainer.createForInstall (); } else { installContainer = OperationContainer.createForUpdate (); } } if (installContainer.canBeAdded (module.getUpdateUnit (), module)) { installContainer.add (module); } } if (installContainer.listAll ().isEmpty ()) { return ; } assert installContainer.listInvalid ().isEmpty () : "No invalid Update Elements " + installContainer.listInvalid (); if (! installContainer.listInvalid ().isEmpty ()) { throw new IllegalArgumentException ("Some are invalid for install: " + installContainer.listInvalid ()); } InstallSupport installSupport = installContainer.getSupport (); ProgressHandle downloadHandle = ProgressHandleFactory.createHandle ( getBundle ("InstallerMissingModules_Download", presentUpdateElements (FindComponentModules.getVisibleUpdateElements (modules4install)))); Validator v = installSupport.doDownload (downloadHandle, false); ProgressHandle verifyHandle = ProgressHandleFactory.createHandle ( getBundle ("InstallerMissingModules_Verify")); Installer i = installSupport.doValidate (v, verifyHandle); ProgressHandle installHandle = ProgressHandleFactory.createHandle ( getBundle ("InstallerMissingModules_Install")); Restarter r = installSupport.doInstall (i, installHandle); if (r != null) { installSupport.doRestartLater (r); // XXX FindBrokenModules.writeEnableLater (modules4repair); RestartIcon restartIcon = RestartNotifier.getFlasher (new Runnable () { public void run () { LifecycleManager.getDefault ().exit (); } }); assert restartIcon != null : "Restart Icon cannot be null."; restartIcon.setToolTipText (getBundle ("InstallerMissingModules_NeedsRestart")); restartIcon.startFlashing (); } else { continueCreating (); } /// XXX FindBrokenModules.clearModulesForRepair (); } public static String presentUpdateElements (Collection elems) { String res = ""; for (UpdateElement el : new LinkedList (elems)) { res += res.length () == 0 ? el.getDisplayName () : ", " + el.getDisplayName (); // NOI18N } return res; } private static void continueCreating () { assert ! SwingUtilities.isEventDispatchThread () : "Cannot be called in EQ."; } private static String getBundle (String key, Object... params) { return NbBundle.getMessage (ModulesInstaller.class, key, params); } } ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/RestartNotifier.java ================================================ /* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.netbeans.modules.consumervisualvm.engine; import java.awt.Component; import javax.swing.Icon; import javax.swing.ImageIcon; import org.openide.awt.StatusLineElementProvider; import org.openide.util.Utilities; /** * * @author Jiri Rechtacek */ public final class RestartNotifier implements StatusLineElementProvider { public Component getStatusLineElement () { return getUpdatesVisualizer (); } private static RestartIcon flasher = null; private static Runnable onMouseClick = null; /** * Return an icon that is flashing when a new internal exception occurs. * Clicking the icon opens the regular exception dialog box. The icon * disappears (is hidden) after a short period of time and the exception * list is cleared. * * @return A flashing icon component or null if console logging is switched on. */ private static Component getUpdatesVisualizer () { if (null == flasher) { ImageIcon img1 = new ImageIcon (Utilities.loadImage ("org/netbeans/modules/autoupdate/featureondemand/resources/restart.png", false)); // NOI18N assert img1 != null : "Icon cannot be null."; flasher = new RestartIcon (img1); } return flasher; } public static RestartIcon getFlasher (Runnable whatRunOnMouseClick) { onMouseClick = whatRunOnMouseClick; return flasher; } public static class RestartIcon extends FlashingIcon { public RestartIcon (Icon img1) { super (img1); DISAPPEAR_DELAY_MILLIS = -1; // don't flashing by http://ui.netbeans.org/docs/ui/AutoUpdate/AutoUpdate.html STOP_FLASHING_DELAY = 0; } /** * User clicked the flashing icon, display the exception window. */ protected void onMouseClick () { if (onMouseClick != null) { onMouseClick.run (); } } /** * The flashing icon disappeared (timed-out), clear the current * exception list. */ protected void timeout () {} } } ================================================ FILE: plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/resources/Bundle.properties ================================================ OpenIDE-Module-Display-Category=Infrastructure OpenIDE-Module-Name=Consumer VisualVM API OpenIDE-Module-Short-Description=Consumer Visual VM API ================================================ FILE: plugins/extapptypes/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.customtype. ================================================ FILE: plugins/extapptypes/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.modules.customtype OpenIDE-Module-Install: org/graalvm/visualvm/modules/customtype/Installer.class OpenIDE-Module-Layer: org/graalvm/visualvm/modules/customtype/layer.xml OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/customtype/Bundle.properties OpenIDE-Module-Provides: org.graalvm.visualvm.modules.customtype OpenIDE-Module-Specification-Version: 1.0 ================================================ FILE: plugins/extapptypes/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/extapptypes/nbproject/project.properties ================================================ is.autoload=true javac.source=1.6 javac.compilerargs=-Xlint -Xlint:-serial ================================================ FILE: plugins/extapptypes/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.customtype org.graalvm.visualvm.api.caching 0-1 0.1 org.graalvm.visualvm.application 0-1 1.1 org.graalvm.visualvm.core 0-1 1.2 org.netbeans.modules.options.api 1 1.5.1 org.openide.dialogs 7.5.1 org.openide.filesystems 7.3.1 org.openide.modules 7.3.1 org.openide.util 8.6.1 org.openide.util.lookup 8.3.1 ================================================ FILE: plugins/extapptypes/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ApplicationType.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype; import org.graalvm.visualvm.modules.customtype.icons.IconCache; import org.graalvm.visualvm.modules.customtype.icons.ImageUtils; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import org.openide.util.RequestProcessor; /** * * @author Jaroslav Bachorik */ public class ApplicationType extends org.graalvm.visualvm.application.type.ApplicationType { public static final String PROPERTY_INFO_URL = "info_url"; // NOI18N public static final String PROPERTY_MAIN_CLASS = "main-class"; // NOI18N private String defName; private String mainClass; private String name; private String version; private String description; private URL iconUrl; private URL infoUrl; private BufferedImage icon; private static BufferedImage DEFAULT_ICON; static { try { DEFAULT_ICON = ImageIO.read(new URL("nbres:/org/graalvm/visualvm/application/resources/application.png")); // NOI18N } catch (Exception e) { Logger.getLogger(ApplicationType.class.getName()).log(Level.SEVERE, "Can not initialize default icon", e); DEFAULT_ICON = null; throw new RuntimeException(e); // something is seriously broken - can't continue -> shut the whole application down } } ApplicationType(String mainClass, String name, String version, String description, URL iconUrl, URL infoUrl) { this.mainClass = mainClass; this.name = name; this.version = version; this.description = description; this.iconUrl = iconUrl; this.infoUrl = infoUrl; } void loadIcon() { if (iconUrl == null) { setIcon(DEFAULT_ICON); } else { try { setIcon(ImageUtils.resizeImage(ImageIO.read(iconUrl), 16, 16)); return; } catch (IOException e) {} } if (iconUrl == null && infoUrl != null) { RequestProcessor.getDefault().post(new Runnable() { @Override public void run() { BufferedImage img = IconCache.getDefault().retrieveObject(infoUrl); if (img != null) { setIcon(img); } } }); } } @Override public String getDescription() { return description; } public void setDescription(String description) { String oldDescription = this.description; this.description = description; firePropertyChange(PROPERTY_DESCRIPTION, oldDescription, description); } public URL getIconURL() { return iconUrl; } public void setIconURL(URL iconUrl) { this.iconUrl = iconUrl; loadIcon(); } public URL getInfoURL() { return infoUrl; } public void setInfoUrl(URL infoUrl) { URL oldUrl = this.infoUrl; this.infoUrl = infoUrl; firePropertyChange(PROPERTY_INFO_URL, oldUrl, infoUrl); loadIcon(); } public String getMainClass() { return mainClass; } public void setMainClass(String mainClass) { String oldClass = this.mainClass; this.mainClass = mainClass; firePropertyChange(PROPERTY_MAIN_CLASS, oldClass, mainClass); } @Override public String getName() { return name; } public void setName(String name) { String oldName = this.name; this.name = name; firePropertyChange(PROPERTY_NAME, oldName, name); } @Override public String getVersion() { return version; } public void setVersion(String version) { String oldVersion = this.version; this.version = version; firePropertyChange(PROPERTY_VERSION, oldVersion, version); } @Override public Image getIcon() { if (icon == null) { return DEFAULT_ICON; } return ImageUtils.resizeImage(icon, 16, 16); } private void setIcon(BufferedImage icon) { BufferedImage oldIcon = this.icon; this.icon = icon != null ? icon : DEFAULT_ICON; firePropertyChange(PROPERTY_ICON, oldIcon, icon); } String getDefName() { return defName; } void setDefName(String defName) { this.defName = defName; } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ApplicationTypeFactory.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import java.util.HashMap; import java.util.Map; /** * * @author Jaroslav Bachorik */ public class ApplicationTypeFactory extends org.graalvm.visualvm.application.type.MainClassApplicationTypeFactory { final private Map typeMap = new HashMap(); final private static class Singleton { final private static ApplicationTypeFactory INSTANCE = new ApplicationTypeFactory(); } final public static ApplicationTypeFactory getDefault() { return Singleton.INSTANCE; } private ApplicationTypeManager manager; private ApplicationTypeFactory() { manager = ApplicationTypeManager.getDefault(); } final public static void initialize() { org.graalvm.visualvm.application.type.ApplicationTypeFactory.getDefault().registerProvider(getDefault()); } final public static void shutdown() { org.graalvm.visualvm.application.type.ApplicationTypeFactory.getDefault().unregisterProvider(getDefault()); } @Override public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) { synchronized(typeMap) { ApplicationType type = typeMap.get(mainClass); if (type == null) { type = findType(mainClass); if (type != null) { typeMap.put(mainClass, type); } } return type; } } private ApplicationType findType(String mainClass) { ApplicationType type = manager.findType(mainClass); if (type != null) { type.loadIcon(); synchronized(typeMap) { typeMap.put(mainClass, type); } } return type; } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ApplicationTypeManager.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype; import org.graalvm.visualvm.api.caching.Cache; import org.graalvm.visualvm.api.caching.CacheFactory; import org.graalvm.visualvm.api.caching.Entry; import org.graalvm.visualvm.api.caching.EntryFactory; import org.graalvm.visualvm.modules.customtype.icons.ImageUtils; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.Random; import java.util.Set; import javax.imageio.ImageIO; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileSystem.AtomicAction; import org.openide.filesystems.Repository; /** * * @author Jaroslav Bachorik */ public class ApplicationTypeManager { final private Random random = new Random(System.currentTimeMillis()); final private FileObject defRepository; final private EntryFactory appTypeResolver = new EntryFactory() { @Override public Entry createEntry(String key) { Enumeration defs = defRepository.getFolders(false); while (defs.hasMoreElements()) { FileObject def = defs.nextElement(); if (def.getExt().equals("def")) { // NOI18N String defMainClass = (String) def.getAttribute("mainClass"); // NOI18N if (defMainClass != null && defMainClass.equals(key)) { String name = (String) def.getAttribute("displayName"); // NOI18N String description = (String) def.getAttribute("description"); // NOI18N description = description.replaceAll("\\s\\s+", " "); String iconPath = (String) def.getAttribute("icon"); // NOI18N String urlPath = (String) def.getAttribute("url"); // NOI18N URL infoUrl = null; URL iconUrl = null; try { if (urlPath != null) { infoUrl = new URL(urlPath); } if (iconPath != null) { iconUrl = new URL(iconPath); } } catch (MalformedURLException e) { e.printStackTrace(); } ApplicationType at = new ApplicationType(key, name, "", description, iconUrl, infoUrl); at.setDefName(def.getNameExt()); return new Entry(at); } } } return null; } }; final private Cache appTypeCache = CacheFactory.getInstance().softMapCache(appTypeResolver); final private static class Singleton { final private static ApplicationTypeManager INSTANCE = new ApplicationTypeManager(); } final public static ApplicationTypeManager getDefault() { return Singleton.INSTANCE; } private ApplicationTypeManager() { defRepository = Repository.getDefault().getDefaultFileSystem().findResource("VisualVM/ApplicationTypes"); // NOI18N } public ApplicationType newType(String mainClass) { return new ApplicationType(mainClass, null, null, null, null, null); } public ApplicationType findType(String mainClass) { return appTypeCache.retrieveObject(mainClass); } public boolean removeType(ApplicationType type) { FileObject def = defRepository.getFileObject(type.getDefName()); if (def != null) { try { def.delete(); appTypeCache.invalidateObject(type.getMainClass()); return true; } catch (IOException e) { } } return false; } public Set listTypes() { Set types = new HashSet(); Collection mainClasses = new ArrayList(); Enumeration defs = defRepository.getFolders(false); while (defs.hasMoreElements()) { FileObject def = defs.nextElement(); if (def.getExt().equals("def")) { // NOI18N String mainClass = (String) def.getAttribute("mainClass"); // NOI18N mainClasses.add(mainClass); } } for(String mainClass : mainClasses) { ApplicationType cachedType = appTypeCache.retrieveObject(mainClass); if (cachedType != null) { types.add(cachedType); } } return types; } public void storeType(final ApplicationType type) throws IOException { Repository.getDefault().getDefaultFileSystem().runAtomicAction(new AtomicAction() { @Override public void run() throws IOException { String defName = type.getDefName(); if (defName == null) { do { defName = calculateDefName(type); } while (defRepository.getFileObject(defName) != null); type.setDefName(defName); } FileObject defFolder = defRepository.getFileObject(defName); if (defFolder == null) { defFolder = defRepository.createFolder(defName); } defFolder.setAttribute("displayName", type.getName()); defFolder.setAttribute("mainClass", type.getMainClass()); if (type.getInfoURL() != null) { defFolder.setAttribute("url", type.getInfoURL().toString()); } else { defFolder.setAttribute("url", null); } if (type.getIconURL() != null) { FileObject iconFile = defFolder.getFileObject("icon.png"); if (iconFile == null) { iconFile = defFolder.createData("icon.png"); } BufferedImage bIcon = ImageIO.read(type.getIconURL()); FileLock lock = iconFile.lock(); OutputStream os = iconFile.getOutputStream(lock); try { ImageIO.write(ImageUtils.resizeImage(bIcon, 16, 16), "png", os); defFolder.setAttribute("icon", iconFile.getURL().toString()); iconFile = null; } finally { os.close(); lock.releaseLock(); } } else { defFolder.setAttribute("icon", null); } } }); } private String calculateDefName(ApplicationType type) { String rndString = String.valueOf(random.nextInt()); return type.getMainClass().replace('.', '_') + "#" + rndString + ".def"; } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/Bundle.properties ================================================ OpenIDE-Module-Display-Category=Infrastructure OpenIDE-Module-Long-Description=\ A declarative approach to defining application types. \n\n\ Based on the application main class it is possible to define its display name, display name, description and URL containing more information. \ The plugin will also try to grab a favicon from the supplied URL to use the most up-to-date application icon. OpenIDE-Module-Name=Custom Application Type OpenIDE-Module-Short-Description=Allows easy, configuration based, creation of application type ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/Installer.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype; import org.openide.modules.ModuleInstall; /** * Manages a module's lifecycle. Remember that an installer is optional and * often not needed at all. */ public class Installer extends ModuleInstall { @Override public void restored() { ApplicationTypeFactory.initialize(); } @Override public void uninstalled() { ApplicationTypeFactory.shutdown(); } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/actions/EditApplicationTypeAction.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype.actions; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.JvmFactory; import org.graalvm.visualvm.application.type.ApplicationTypeFactory; import org.graalvm.visualvm.modules.customtype.ApplicationType; import org.graalvm.visualvm.modules.customtype.ApplicationTypeManager; import org.graalvm.visualvm.modules.customtype.ui.ApplicationTypeForm; import org.graalvm.visualvm.core.ui.actions.DataSourceAction; import java.awt.Dialog; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.Set; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; /** * * @author Jaroslav Bachorik */ public class EditApplicationTypeAction extends DataSourceAction { private Application selectedApp = null; final private static class Singleton { final private static EditApplicationTypeAction INSTANCE = new EditApplicationTypeAction(); } final public static EditApplicationTypeAction getDefault() { return Singleton.INSTANCE; } private EditApplicationTypeAction() { super(Application.class); putValue(NAME, "Edit Application Type..."); } @Override protected void updateState(Set selectedApps) { if (selectedApps.size() == 1) { selectedApp = selectedApps.iterator().next(); org.graalvm.visualvm.application.type.ApplicationType at = ApplicationTypeFactory.getApplicationTypeFor(selectedApp); if (at instanceof ApplicationType) { if (!JvmFactory.getJVMFor(selectedApp).getMainClass().isEmpty()) { setEnabled(true); return; } } selectedApp = null; setEnabled(false); } else { selectedApp = null; setEnabled(false); } } @Override public void actionPerformed(ActionEvent e) { final ApplicationType at = (ApplicationType)ApplicationTypeFactory.getApplicationTypeFor(selectedApp); final ApplicationTypeForm form = new ApplicationTypeForm(at); final DialogDescriptor[] dd = new DialogDescriptor[1]; dd[0] = new DialogDescriptor(form, "Application Type Details", true, new Object[]{form.getValidationSupport().getOkButton(), DialogDescriptor.CANCEL_OPTION}, form.getValidationSupport().getOkButton(), DialogDescriptor.DEFAULT_ALIGN, null, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == form.getValidationSupport().getOkButton() && form.storeData()) { dd[0].setClosingOptions(new Object[] {form.getValidationSupport().getOkButton()}); } } }); dd[0].setClosingOptions(new Object[] {DialogDescriptor.CANCEL_OPTION}); Dialog dlg = DialogDisplayer.getDefault().createDialog(dd[0]); dlg.setVisible(true); if (dd[0].getValue() == form.getValidationSupport().getOkButton()) { try { ApplicationTypeManager.getDefault().storeType(at); } catch (IOException ex) { ex.printStackTrace(); } } } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/actions/NewApplicationTypeAction.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype.actions; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.application.jvm.JvmFactory; import org.graalvm.visualvm.application.type.ApplicationTypeFactory; import org.graalvm.visualvm.application.type.DefaultApplicationType; import org.graalvm.visualvm.modules.customtype.ApplicationTypeManager; import org.graalvm.visualvm.modules.customtype.ui.ApplicationTypeForm; import org.graalvm.visualvm.core.ui.actions.DataSourceAction; import org.graalvm.visualvm.modules.customtype.ApplicationType; import java.awt.Dialog; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.Set; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; /** * * @author Jaroslav Bachorik */ public class NewApplicationTypeAction extends DataSourceAction { private Application selectedApp = null; final private static class Singleton { final private static NewApplicationTypeAction INSTANCE = new NewApplicationTypeAction(); } final public static NewApplicationTypeAction getDefault() { return Singleton.INSTANCE; } private NewApplicationTypeAction() { super(Application.class); putValue(NAME, "Create New Application Type..."); } @Override protected void updateState(Set selectedApps) { if (selectedApps.size() == 1) { selectedApp = selectedApps.iterator().next(); org.graalvm.visualvm.application.type.ApplicationType at = ApplicationTypeFactory.getApplicationTypeFor(selectedApp); if (at instanceof DefaultApplicationType) { if (!JvmFactory.getJVMFor(selectedApp).getMainClass().isEmpty()) { setEnabled(true); return; } } selectedApp = null; setEnabled(false); } else { selectedApp = null; setEnabled(false); } } @Override public void actionPerformed(ActionEvent e) { Jvm jvm = JvmFactory.getJVMFor(selectedApp); if (jvm != null) { ApplicationType eat = ApplicationTypeManager.getDefault().newType(jvm.getMainClass()); final ApplicationTypeForm form = new ApplicationTypeForm(eat); final DialogDescriptor[] dd = new DialogDescriptor[1]; dd[0] = new DialogDescriptor(form, "New Application Type Details", true, new Object[]{form.getValidationSupport().getOkButton(), DialogDescriptor.CANCEL_OPTION}, form.getValidationSupport().getOkButton(), DialogDescriptor.DEFAULT_ALIGN, null, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getSource().equals(form.getValidationSupport().getOkButton()) && form.storeData()) { dd[0].setClosingOptions(new Object[] {form.getValidationSupport().getOkButton()}); } } }); dd[0].setClosingOptions(new Object[] {DialogDescriptor.CANCEL_OPTION}); Dialog dlg = DialogDisplayer.getDefault().createDialog(dd[0]); dlg.setVisible(true); if (dd[0].getValue() == form.getValidationSupport().getOkButton()) { try { ApplicationTypeManager.getDefault().storeType(eat); } catch (IOException ex) { ex.printStackTrace(); } } } } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/actions/ValidationSupport.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype.actions; import javax.swing.JButton; /** * * @author Jaroslav Bachorik */ abstract public class ValidationSupport { final private JButton OK_BUTTON = new JButton("OK"); public ValidationSupport() { } final public JButton getOkButton() { return OK_BUTTON; } final public void updateValidity() { OK_BUTTON.setEnabled(isValid()); } abstract public boolean isValid(); final public static ValidationSupport DEFAULT = new ValidationSupport() { @Override public boolean isValid() { return true; } }; } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/icons/FileImagePersistor.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype.icons; import org.graalvm.visualvm.api.caching.Entry; import org.graalvm.visualvm.api.caching.Persistor; import org.graalvm.visualvm.core.datasource.Storage; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.net.URL; import javax.imageio.ImageIO; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; /** * * @author Jaroslav Bachorik */ public class FileImagePersistor implements Persistor { final private static String APPTYPE_ICON_CACHE = "apptype-icon-cache"; // NOI18N final private FileObject storage; public FileImagePersistor() throws InstantiationException { try { FileObject globalStorage = FileUtil.toFileObject(Storage.getPersistentStorageDirectory()); FileObject aStorage = globalStorage.getFileObject(APPTYPE_ICON_CACHE); if (aStorage == null) { storage = globalStorage.createFolder(APPTYPE_ICON_CACHE); } else { storage = aStorage; } } catch (IOException ex) { throw new InstantiationException(ex.getLocalizedMessage()); } } @Override public Entry retrieve(URL key) { InputStream is = null; try { FileObject imageFile = storage.getFileObject(entryFileName(key)); if (imageFile != null) { is = imageFile.getInputStream(); return new Entry(ImageIO.read(is), imageFile.lastModified().getTime()); } else { return null; } } catch (IOException ex) { ex.printStackTrace(); return null; } finally { if (is != null) { try { is.close(); } catch (Exception e){} } } } @Override public void store(URL key, Entry value) { if (value.getContent() == null) return; FileLock outputLock = null; try { String fileName = entryFileName(key); FileObject imageFile = storage.getFileObject(fileName); if (imageFile == null) { imageFile = storage.createData(fileName); } if (imageFile != null) { outputLock = imageFile.lock(); ImageIO.write(value.getContent(), "png", imageFile.getOutputStream(outputLock)); } } catch (IOException ex) { ex.printStackTrace(); } finally { if (outputLock != null) { outputLock.releaseLock(); } } } private static String entryFileName(URL url) { return url.toString().replace(':', '#').replace('/', '_'); } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/icons/IconCache.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype.icons; import org.graalvm.visualvm.api.caching.Cache; import org.graalvm.visualvm.api.caching.CacheFactory; import org.graalvm.visualvm.api.caching.Entry; import org.graalvm.visualvm.api.caching.EntryFactory; import org.graalvm.visualvm.api.caching.Persistor; import java.awt.image.BufferedImage; import java.net.URL; /** * * @author Jaroslav Bachorik */ public class IconCache extends Cache { final private IconResolver resolver = new IconResolver(); final private Cache delegate; final private static class Singleton { final private static IconCache INSTANCE = new IconCache(); } final public static IconCache getDefault() { return Singleton.INSTANCE; } private IconCache() { Persistor persistor; try { persistor = new FileImagePersistor(); } catch (InstantiationException e) { persistor = Persistor.DEFAULT; } delegate = CacheFactory.getInstance().softMapCache(new EntryFactory() { @Override public Entry createEntry(URL key) { BufferedImage img = resolver.resolveIcon(key); if (img != null) { img = ImageUtils.resizeImage(img, 16, 16); } return new Entry(resolver.resolveIcon(key)); } }, persistor); } @Override public long getTTL() { return delegate.getTTL(); } @Override public BufferedImage invalidateObject(URL key) { return delegate.invalidateObject(key); } @Override public BufferedImage retrieveObject(URL key) { return delegate.retrieveObject(key); } @Override public void setTTL(long ttl) { delegate.setTTL(ttl); } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/icons/IconResolver.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype.icons; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.imageio.ImageIO; /** * * @author Jaroslav Bachorik */ class IconResolver { final private static Pattern favicoLinkPattern = Pattern.compile("\\", Pattern.MULTILINE | Pattern.DOTALL); final private static Pattern favicoHrefPattern = Pattern.compile("href=[\\\"'](.+?)[\\\"']", Pattern.MULTILINE | Pattern.DOTALL); final private static String[] extensions = new String[]{"png", "gif", "jpg", "jpeg"}; BufferedImage resolveIcon(URL url) { BufferedImage resolvedImage = null; for (String extension : extensions) { String favIcon = "favicon." + extension; try { URL favicoUrl = new URL(url.toString() + "/" + favIcon); resolvedImage = ImageIO.read(favicoUrl); if (resolvedImage != null && resolvedImage.getWidth() > -1) { break; } } catch (IOException ex) { // ignore } } if (resolvedImage == null) { resolvedImage = resolveFromLink(url); } return resolvedImage != null ? (resolvedImage.getWidth() > -1 ? resolvedImage : null) : null; } private synchronized BufferedImage resolveFromLink(URL url) { try { String index = readIndex(url.openStream()); Matcher linkMatcher = favicoLinkPattern.matcher(index); String favicoPath = null; while (linkMatcher.find()) { String content = linkMatcher.group(1); if (content.contains("shortcut") || content.contains("icon")) { Matcher hrefMatcher = favicoHrefPattern.matcher(content); if (hrefMatcher.find()) { favicoPath = hrefMatcher.group(1); if (isSupported(favicoPath)) { break; } else { favicoPath = null; } } } } if (favicoPath != null) { URL favicoUrl = null; if (favicoPath.startsWith("/")) { // absolute path favicoUrl = new URL(url.getProtocol(), url.getHost(), favicoPath); } else { favicoUrl = new URL(url.getProtocol(), url.getHost(), url.getFile() + "/" + favicoPath); } Logger.getLogger(IconResolver.class.getName()).fine("Resolving image: " + favicoUrl.toString()); return ImageIO.read(favicoUrl); } } catch (IOException e) { e.printStackTrace(); } return null; } private String readIndex(InputStream is) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line = null; try { do { line = br.readLine(); if (line != null) { sb.append(line).append('\n'); } } while (line != null); } finally { try { is.close(); } catch (IOException e) { } } return sb.toString(); } private boolean isSupported(String imagePath) { int jsIndex = imagePath.indexOf(";"); if (jsIndex > -1) { imagePath = imagePath.substring(0, jsIndex); } for (String ext : extensions) { if (imagePath.endsWith(ext)) { return true; } } return false; } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/icons/ImageUtils.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype.icons; import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; /** * * @author Jaroslav Bachorik */ public class ImageUtils { final public static BufferedImage resizeImage(BufferedImage img, int width, int height) { Graphics2D gin = img.createGraphics(); GraphicsConfiguration gc = gin.getDeviceConfiguration(); gin.dispose(); BufferedImage dst = gc.createCompatibleImage(width, height, BufferedImage.BITMASK); Graphics2D gr = dst.createGraphics(); gr.setComposite(AlphaComposite.Src); AffineTransform at = AffineTransform.getScaleInstance((double)width/img.getWidth(), (double)height/img.getHeight()); gr.drawRenderedImage(img,at); return dst; } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/layer.xml ================================================ ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/options/ApplicationTypeOptionsCategory.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype.options; import javax.swing.Icon; import javax.swing.ImageIcon; import org.netbeans.spi.options.OptionsCategory; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.ImageUtilities; /** * * @author Jaroslav Bachorik */ public class ApplicationTypeOptionsCategory extends OptionsCategory { final public static ApplicationTypeOptionsCategory instance() { return new ApplicationTypeOptionsCategory(); } @Override public OptionsPanelController create() { return new ApplicationTypesOptionsPanelController(); } @Override public String getCategoryName() { return "Application Types"; } @Override public String getTitle() { return "VisualVM"; } @Override public Icon getIcon() { return new ImageIcon(ImageUtilities.loadImage("org/graalvm/visualvm/modules/customtype/resources/type_options.png")); } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/options/ApplicationTypeOptionsPanel.form ================================================

<ResourceString bundle="org/graalvm/visualvm/modules/customtype/options/Bundle.properties" key="ApplicationTypeOptionsPanel.appTypeTable.columnModel.title0" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> <ResourceString bundle="org/graalvm/visualvm/modules/customtype/options/Bundle.properties" key="ApplicationTypeOptionsPanel.appTypeTable.columnModel.title1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/options/ApplicationTypeOptionsPanel.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * ApplicationTypeOptionsPanel.java * * Created on Nov 3, 2008, 1:33:55 PM */ package org.graalvm.visualvm.modules.customtype.options; import org.graalvm.visualvm.modules.customtype.ApplicationType; import org.graalvm.visualvm.modules.customtype.ApplicationTypeManager; import org.graalvm.visualvm.modules.customtype.ui.ApplicationTypeForm; import java.awt.Dialog; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; /** * * @author Jaroslav Bachorik */ public class ApplicationTypeOptionsPanel extends javax.swing.JPanel { private static class AppTypeTableMode extends AbstractTableModel { final private List types = new ArrayList(); @Override public int getColumnCount() { return 2; } @Override public int getRowCount() { synchronized (types) { return types.size(); } } @Override public Object getValueAt(int rowIndex, int columnIndex) { synchronized (types) { switch (columnIndex) { case 0: { return types.get(rowIndex).getName(); } case 1: { return true; } default: { return null; } } } } ApplicationType getTypeAt(int selectedIndex) { synchronized (types) { return types.get(selectedIndex); } } void update() { synchronized (types) { types.clear(); types.addAll(ApplicationTypeManager.getDefault().listTypes()); fireTableDataChanged(); } } } final private AppTypeTableMode tableModel = new AppTypeTableMode(); /** Creates new form ApplicationTypeOptionsPanel */ public ApplicationTypeOptionsPanel() { initComponents(); appTypeTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { menuEdit.setEnabled(appTypeTable.getSelectedRowCount() == 1); menuDelete.setEnabled(appTypeTable.getSelectedRowCount() > 0); } } }); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { tablePopupMenu = new javax.swing.JPopupMenu(); menuNew = new javax.swing.JMenuItem(); menuEdit = new javax.swing.JMenuItem(); jSeparator1 = new javax.swing.JSeparator(); menuDelete = new javax.swing.JMenuItem(); jLabel1 = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); appTypeTable = new javax.swing.JTable(); menuNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_INSERT, java.awt.event.InputEvent.CTRL_MASK)); menuNew.setMnemonic('C'); menuNew.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, "ApplicationTypeOptionsPanel.menuNew.text")); // NOI18N menuNew.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuNewActionPerformed(evt); } }); tablePopupMenu.add(menuNew); menuEdit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER, java.awt.event.InputEvent.CTRL_MASK)); menuEdit.setMnemonic('E'); menuEdit.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, "ApplicationTypeOptionsPanel.menuEdit.text")); // NOI18N menuEdit.setEnabled(false); menuEdit.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { editApplicationType(evt); } }); tablePopupMenu.add(menuEdit); tablePopupMenu.add(jSeparator1); menuDelete.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE, 0)); menuDelete.setMnemonic('D'); menuDelete.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, "ApplicationTypeOptionsPanel.menuDelete.text")); // NOI18N menuDelete.setEnabled(false); menuDelete.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteApptype(evt); } }); tablePopupMenu.add(menuDelete); jLabel1.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); jLabel1.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, "ApplicationTypeOptionsPanel.jLabel1.text")); // NOI18N appTypeTable.setAutoCreateRowSorter(true); appTypeTable.setModel(tableModel); appTypeTable.setComponentPopupMenu(tablePopupMenu); appTypeTable.setOpaque(false); appTypeTable.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); jScrollPane1.setViewportView(appTypeTable); appTypeTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); appTypeTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, "ApplicationTypeOptionsPanel.appTypeTable.columnModel.title0")); // NOI18N appTypeTable.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, "ApplicationTypeOptionsPanel.appTypeTable.columnModel.title1")); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE) .addComponent(jLabel1)) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 275, Short.MAX_VALUE) .addContainerGap()) ); }// //GEN-END:initComponents private void editApplicationType(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editApplicationType final ApplicationType at = tableModel.getTypeAt(appTypeTable.getSelectedRow()); final ApplicationTypeForm form = new ApplicationTypeForm(at); final DialogDescriptor[] dd = new DialogDescriptor[1]; dd[0] = new DialogDescriptor(form, "Application Type Details", true, new Object[]{form.getValidationSupport().getOkButton(), DialogDescriptor.CANCEL_OPTION}, form.getValidationSupport().getOkButton(), DialogDescriptor.DEFAULT_ALIGN, null, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == form.getValidationSupport().getOkButton() && form.storeData()) { dd[0].setClosingOptions(new Object[]{form.getValidationSupport().getOkButton()}); } } }); dd[0].setClosingOptions(new Object[]{DialogDescriptor.CANCEL_OPTION}); Dialog dlg = DialogDisplayer.getDefault().createDialog(dd[0]); dlg.setVisible(true); if (dd[0].getValue() == form.getValidationSupport().getOkButton()) { try { ApplicationTypeManager.getDefault().storeType(at); } catch (IOException ex) { ex.printStackTrace(); } } }//GEN-LAST:event_editApplicationType private void menuNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuNewActionPerformed ApplicationType eat = ApplicationTypeManager.getDefault().newType(""); final ApplicationTypeForm form = new ApplicationTypeForm(eat); final DialogDescriptor[] dd = new DialogDescriptor[1]; dd[0] = new DialogDescriptor(form, "New Application Type Details", true, new Object[]{form.getValidationSupport().getOkButton(), DialogDescriptor.CANCEL_OPTION}, form.getValidationSupport().getOkButton(), DialogDescriptor.DEFAULT_ALIGN, null, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getSource().equals(form.getValidationSupport().getOkButton()) && form.storeData()) { dd[0].setClosingOptions(new Object[]{form.getValidationSupport().getOkButton()}); } } }); dd[0].setClosingOptions(new Object[]{DialogDescriptor.CANCEL_OPTION}); Dialog dlg = DialogDisplayer.getDefault().createDialog(dd[0]); dlg.setVisible(true); if (dd[0].getValue() == form.getValidationSupport().getOkButton()) { try { ApplicationTypeManager.getDefault().storeType(eat); } catch (IOException ex) { ex.printStackTrace(); } } tableModel.update(); }//GEN-LAST:event_menuNewActionPerformed private void deleteApptype(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteApptype final ApplicationType at = tableModel.getTypeAt(appTypeTable.getSelectedRow()); ApplicationTypeManager.getDefault().removeType(at); tableModel.update(); }//GEN-LAST:event_deleteApptype // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTable appTypeTable; private javax.swing.JLabel jLabel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSeparator jSeparator1; private javax.swing.JMenuItem menuDelete; private javax.swing.JMenuItem menuEdit; private javax.swing.JMenuItem menuNew; private javax.swing.JPopupMenu tablePopupMenu; // End of variables declaration//GEN-END:variables void load() { tableModel.update(); } void store() { System.err.println("Store"); } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/options/ApplicationTypesOptionsPanelController.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.customtype.options; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import javax.swing.JComponent; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.HelpCtx; import org.openide.util.Lookup; /** * * @author Jaroslav Bachorik */ public class ApplicationTypesOptionsPanelController extends OptionsPanelController{ volatile private ApplicationTypeOptionsPanel panel; final private PropertyChangeSupport pcs = new PropertyChangeSupport(this); @Override public void addPropertyChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } @Override public void applyChanges() { getPanel().store(); } @Override public void cancel() { // no-op } @Override public JComponent getComponent(Lookup arg0) { return getPanel(); } @Override public HelpCtx getHelpCtx() { return null; } @Override public boolean isChanged() { return true; } @Override public boolean isValid() { return true; } @Override public void removePropertyChangeListener(PropertyChangeListener listener) { pcs.removePropertyChangeListener(listener); } @Override public void update() { getPanel().load(); } synchronized private ApplicationTypeOptionsPanel getPanel() { if (panel == null) { panel = new ApplicationTypeOptionsPanel(); } return panel; } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/options/Bundle.properties ================================================ # Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. * # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). * # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * ApplicationTypeOptionsPanel.jLabel1.text=Application Types ApplicationTypeOptionsPanel.jTable1.columnModel.title3=Title 4 ApplicationTypeOptionsPanel.jTable1.columnModel.title2=Title 3 ApplicationTypeOptionsPanel.appTypeTable.columnModel.title1=Active ApplicationTypeOptionsPanel.appTypeTable.columnModel.title0=Application Type ApplicationTypeOptionsPanel.menuNew.text=Create... ApplicationTypeOptionsPanel.menuEdit.text=Edit... ApplicationTypeOptionsPanel.menuDelete.text=Delete ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ui/ApplicationTypeForm.form ================================================
================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ui/ApplicationTypeForm.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * NewApplicationTypeForm.java * * Created on Oct 22, 2008, 2:40:07 PM */ package org.graalvm.visualvm.modules.customtype.ui; import org.graalvm.visualvm.modules.customtype.ApplicationType; import org.graalvm.visualvm.modules.customtype.actions.ValidationSupport; import org.graalvm.visualvm.modules.customtype.icons.ImageUtils; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFileChooser; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.filechooser.FileFilter; /** * * @author Jaroslav Bachorik */ public class ApplicationTypeForm extends javax.swing.JPanel { final private static String defaultName = "<" + "New Application Type" + ">"; final private static String defaultDescription = "<" + "Put description here" + ">"; final private static ImageIcon DEFAULT_ICON = new javax.swing.ImageIcon(ApplicationTypeForm.class.getResource("/org/graalvm/visualvm/modules/customtype/ui/application.png")); // NOI18N private ApplicationType applicationType; private File iconFile = null; private boolean iconFileReset = false; private ValidationSupport validationSupport = new ValidationSupport() { @Override public boolean isValid() { return !appTypeName.getText().isEmpty(); } }; /** Creates new form NewApplicationTypeForm */ public ApplicationTypeForm(ApplicationType appType) { initComponents(); applicationType = appType; appTypeName.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { validationSupport.updateValidity(); } @Override public void removeUpdate(DocumentEvent e) { validationSupport.updateValidity(); } @Override public void changedUpdate(DocumentEvent e) { validationSupport.updateValidity(); } }); loadData(); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { iconMenu = new javax.swing.JPopupMenu(); resetIcon = new javax.swing.JMenuItem(); nameLabel = new javax.swing.JLabel(); mainClassLabel = new javax.swing.JLabel(); urlLabel = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); appTypeName = new javax.swing.JTextField(); appTypeMainClass = new javax.swing.JTextField(); appTypeUrl = new javax.swing.JTextField(); descriptionLabel = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); appTypeDescription = new javax.swing.JTextArea(); jScrollPane2 = new javax.swing.JScrollPane(); jTextPane1 = new javax.swing.JTextPane(); appTypeIcon = new javax.swing.JButton(); resetIcon.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.resetIcon.text")); // NOI18N resetIcon.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { resetIconActionPerformed(evt); } }); iconMenu.add(resetIcon); nameLabel.setDisplayedMnemonic('N'); nameLabel.setLabelFor(appTypeName); nameLabel.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.nameLabel.text")); // NOI18N mainClassLabel.setDisplayedMnemonic('C'); mainClassLabel.setLabelFor(appTypeMainClass); mainClassLabel.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.mainClassLabel.text")); // NOI18N urlLabel.setDisplayedMnemonic('U'); urlLabel.setLabelFor(appTypeUrl); urlLabel.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.urlLabel.text")); // NOI18N jLabel4.setDisplayedMnemonic('I'); jLabel4.setLabelFor(appTypeIcon); jLabel4.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.jLabel4.text")); // NOI18N appTypeName.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.appTypeName.text")); // NOI18N appTypeName.setFocusCycleRoot(true); appTypeName.setNextFocusableComponent(appTypeIcon); appTypeName.addFocusListener(new java.awt.event.FocusAdapter() { public void focusGained(java.awt.event.FocusEvent evt) { appTypeNameFocusGained(evt); } public void focusLost(java.awt.event.FocusEvent evt) { appTypeNameFocusLost(evt); } }); appTypeName.addKeyListener(new java.awt.event.KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent evt) { appTypeNameKeyTyped(evt); } }); appTypeMainClass.setEditable(false); appTypeMainClass.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.appTypeMainClass.text")); // NOI18N appTypeMainClass.setNextFocusableComponent(appTypeUrl); appTypeUrl.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.appTypeUrl.text")); // NOI18N appTypeUrl.setNextFocusableComponent(appTypeDescription); appTypeUrl.addFocusListener(new java.awt.event.FocusAdapter() { public void focusGained(java.awt.event.FocusEvent evt) { appTypeUrlFocusGained(evt); } public void focusLost(java.awt.event.FocusEvent evt) { appTypeUrlFocusLost(evt); } }); descriptionLabel.setDisplayedMnemonic('D'); descriptionLabel.setLabelFor(appTypeDescription); descriptionLabel.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.descriptionLabel.text")); // NOI18N appTypeDescription.setColumns(20); appTypeDescription.setLineWrap(true); appTypeDescription.setRows(5); appTypeDescription.setTabSize(4); appTypeDescription.setWrapStyleWord(true); appTypeDescription.setNextFocusableComponent(appTypeName); appTypeDescription.addFocusListener(new java.awt.event.FocusAdapter() { public void focusGained(java.awt.event.FocusEvent evt) { appTypeDescriptionFocusGained(evt); } public void focusLost(java.awt.event.FocusEvent evt) { appTypeDescriptionFocusLost(evt); } }); jScrollPane1.setViewportView(appTypeDescription); jScrollPane2.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); jScrollPane2.setViewportBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); jScrollPane2.setOpaque(false); jTextPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); jTextPane1.setContentType(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.jTextPane1.contentType")); // NOI18N jTextPane1.setEditable(false); jTextPane1.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.jTextPane1.text")); // NOI18N jScrollPane2.setViewportView(jTextPane1); appTypeIcon.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/graalvm/visualvm/modules/customtype/ui/application.png"))); // NOI18N appTypeIcon.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, "ApplicationTypeForm.appTypeIcon.text")); // NOI18N appTypeIcon.setComponentPopupMenu(iconMenu); appTypeIcon.setHideActionText(true); appTypeIcon.setNextFocusableComponent(appTypeMainClass); appTypeIcon.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { appTypeIconActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE) .addComponent(mainClassLabel, javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(urlLabel) .addComponent(descriptionLabel) .addComponent(nameLabel)) .addGap(8, 8, 8) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 379, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(appTypeName, javax.swing.GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(appTypeIcon)) .addComponent(appTypeUrl, javax.swing.GroupLayout.DEFAULT_SIZE, 379, Short.MAX_VALUE) .addComponent(appTypeMainClass, javax.swing.GroupLayout.DEFAULT_SIZE, 379, Short.MAX_VALUE)))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(nameLabel) .addComponent(appTypeName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(6, 6, 6)) .addGroup(layout.createSequentialGroup() .addComponent(appTypeIcon) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(mainClassLabel) .addComponent(appTypeMainClass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(urlLabel) .addComponent(appTypeUrl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(descriptionLabel) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 99, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); }// //GEN-END:initComponents private void appTypeNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeNameFocusGained appTypeName.setSelectionStart(0); appTypeName.setSelectionEnd(appTypeName.getText().length()); }//GEN-LAST:event_appTypeNameFocusGained private void appTypeNameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeNameFocusLost appTypeName.setSelectionEnd(0); }//GEN-LAST:event_appTypeNameFocusLost private void appTypeDescriptionFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeDescriptionFocusGained appTypeDescription.setSelectionStart(0); appTypeDescription.setSelectionEnd(appTypeDescription.getText().length()); }//GEN-LAST:event_appTypeDescriptionFocusGained private void appTypeDescriptionFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeDescriptionFocusLost appTypeDescription.setSelectionEnd(0); }//GEN-LAST:event_appTypeDescriptionFocusLost private void appTypeUrlFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeUrlFocusGained appTypeUrl.setSelectionStart(0); appTypeUrl.setSelectionEnd(appTypeUrl.getText().length()); }//GEN-LAST:event_appTypeUrlFocusGained private void appTypeUrlFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeUrlFocusLost appTypeUrl.setSelectionEnd(0); }//GEN-LAST:event_appTypeUrlFocusLost private void appTypeNameKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_appTypeNameKeyTyped validationSupport.updateValidity(); }//GEN-LAST:event_appTypeNameKeyTyped private void appTypeIconActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_appTypeIconActionPerformed JFileChooser jfc = new JFileChooser(); jfc.setFileFilter(new FileFilter() { @Override public boolean accept(File f) { return (f.isDirectory() || f.getName().endsWith("png") || f.getName().endsWith("jpg") || f.getName().endsWith("jpeg") || f.getName().endsWith("gif")); } @Override public String getDescription() { return "Icon files"; } }); if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { iconFile = jfc.getSelectedFile(); try { BufferedImage img = ImageIO.read(iconFile); appTypeIcon.setIcon(new ImageIcon(ImageUtils.resizeImage(img, 16, 16))); iconFileReset = false; } catch (IOException iOException) { } } }//GEN-LAST:event_appTypeIconActionPerformed private void resetIconActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetIconActionPerformed iconFile = null; appTypeIcon.setIcon(DEFAULT_ICON); iconFileReset = true; }//GEN-LAST:event_resetIconActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTextArea appTypeDescription; private javax.swing.JButton appTypeIcon; private javax.swing.JTextField appTypeMainClass; private javax.swing.JTextField appTypeName; private javax.swing.JTextField appTypeUrl; private javax.swing.JLabel descriptionLabel; private javax.swing.JPopupMenu iconMenu; private javax.swing.JLabel jLabel4; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JTextPane jTextPane1; private javax.swing.JLabel mainClassLabel; private javax.swing.JLabel nameLabel; private javax.swing.JMenuItem resetIcon; private javax.swing.JLabel urlLabel; // End of variables declaration//GEN-END:variables private void loadData() { iconFileReset = false; appTypeName.setText(applicationType.getName() == null || applicationType.getName().isEmpty() ? defaultName : applicationType.getName()); appTypeMainClass.setText(applicationType.getMainClass()); appTypeUrl.setText(applicationType.getInfoURL() != null ? applicationType.getInfoURL().toString() : ""); appTypeDescription.setText((applicationType.getDescription() != null && !applicationType.getDescription().isEmpty()) ? applicationType.getDescription() : defaultDescription); if (applicationType.getIconURL() != null) { BufferedImage iconImage = null; try { iconImage = ImageIO.read(applicationType.getIconURL()); } catch (IOException e) { } if (iconImage != null) { iconImage = ImageUtils.resizeImage(iconImage, 16, 16); } appTypeIcon.setIcon(new ImageIcon(iconImage)); } else { appTypeIcon.setIcon(DEFAULT_ICON); } appTypeMainClass.setEditable(appTypeMainClass.getText().isEmpty()); } public boolean storeData() { boolean result = true; if (appTypeName.getText().isEmpty() || appTypeName.getText().equals(defaultName)) { nameLabel.setForeground(Color.RED); result = false; } else { nameLabel.setForeground(Color.BLACK); } URL infoUrl = null; if (!appTypeUrl.getText().isEmpty()) { try { infoUrl = new URL(appTypeUrl.getText()); urlLabel.setForeground(Color.BLACK); } catch (MalformedURLException e) { urlLabel.setForeground(Color.RED); result = false; } } else { urlLabel.setForeground(Color.BLACK); } if (result) { applicationType.setName(appTypeName.getText()); applicationType.setMainClass(appTypeMainClass.getText()); applicationType.setDescription(appTypeDescription.getText().equals(defaultDescription) ? "" : appTypeDescription.getText()); if (iconFileReset) { applicationType.setIconURL(null); } else if (iconFile != null) { try { applicationType.setIconURL(iconFile.toURI().toURL()); } catch (IOException e) { } } applicationType.setInfoUrl(infoUrl); } return result; } public ValidationSupport getValidationSupport() { return validationSupport; } } ================================================ FILE: plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ui/Bundle.properties ================================================ # Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. * # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). * # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * ApplicationTypeForm.descriptionLabel.text=Description: ApplicationTypeForm.appTypeUrl.text= ApplicationTypeForm.appTypeMainClass.text= ApplicationTypeForm.appTypeName.text= ApplicationTypeForm.jLabel4.text=Icon: ApplicationTypeForm.nameLabel.text=Name: ApplicationTypeForm.mainClassLabel.text=Main Class: ApplicationTypeForm.urlLabel.text=Info URL: ApplicationTypeForm.jTextPane1.contentType=text/html ApplicationTypeForm.jTextPane1.text=\n \n Note: All the changes will be visible only after you have restarted VisualVM or the monitored application\n \n\n ApplicationTypeForm.appTypeIcon.text= ApplicationTypeForm.resetIcon.text=Reset Icon ================================================ FILE: plugins/extapptypes.lib/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.customtype.lib. ================================================ FILE: plugins/extapptypes.lib/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.modules.customtype.lib OpenIDE-Module-Layer: org/graalvm/visualvm/modules/customtype/lib/layer.xml OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/customtype/lib/Bundle.properties OpenIDE-Module-Requires: org.graalvm.visualvm.modules.customtype OpenIDE-Module-Specification-Version: 1.0 ================================================ FILE: plugins/extapptypes.lib/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/extapptypes.lib/nbproject/project.properties ================================================ javac.source=1.5 javac.compilerargs=-Xlint -Xlint:-serial ================================================ FILE: plugins/extapptypes.lib/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.customtype.lib ================================================ FILE: plugins/extapptypes.lib/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/extapptypes.lib/src/org/graalvm/visualvm/modules/customtype/lib/Bundle.properties ================================================ OpenIDE-Module-Display-Category=Infrastructure OpenIDE-Module-Long-Description=\ This is a growing collection of application types for the most popular Java applicaitons.\n\n\ It contains application types for applications such as jEdit, PMD, FindBugs, aTunes etc. OpenIDE-Module-Name=Custom Application Types - Collection OpenIDE-Module-Short-Description=Application types for widely used Java applications ================================================ FILE: plugins/extapptypes.lib/src/org/graalvm/visualvm/modules/customtype/lib/layer.xml ================================================ ================================================ FILE: plugins/extensions/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.extensions. ================================================ FILE: plugins/extensions/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.modules.extensions/2 OpenIDE-Module-Install: org/graalvm/visualvm/modules/extensions/Installer.class OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/extensions/Bundle.properties OpenIDE-Module-Specification-Version: 2.0 ================================================ FILE: plugins/extensions/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/extensions/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=81664b27 build.xml.script.CRC32=dcc223e1 build.xml.stylesheet.CRC32=05353c81 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=7dd7675e nbproject/build-impl.xml.script.CRC32=d3d069fa nbproject/build-impl.xml.stylesheet.CRC32=deb65f65 ================================================ FILE: plugins/extensions/nbproject/project.properties ================================================ # # Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. javac.source=1.5 javac.compilerargs=-Xlint -Xlint:-serial license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Luis-Miguel Alventosa, Tomas Hurka cp.extra=${tools.jar} module.javadoc.packages=org.graalvm.visualvm.modules.extensions.* ================================================ FILE: plugins/extensions/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.extensions org.graalvm.visualvm.application 2 2.0 org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.tools 2 2.0 org.openide.modules 7.3.1 org.openide.util.ui 9.8 ================================================ FILE: plugins/extensions/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/extensions/src/org/graalvm/visualvm/modules/extensions/Bundle.properties ================================================ # # Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Platform OpenIDE-Module-Long-Description=\ The intent of this module is to add support for additional functionality (such as new JDKs, JVMs, HotSpot versions, ...) not supported by the VisualVM core modules at the time this VisualVM was released. OpenIDE-Module-Name=VisualVM-Extensions OpenIDE-Module-Short-Description=Extends VisualVM core functionality. ================================================ FILE: plugins/extensions/src/org/graalvm/visualvm/modules/extensions/DiabloJvmJvmstatModelProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.extensions; import org.graalvm.visualvm.core.model.AbstractModelProvider; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.tools.jvmstat.JvmstatModel; import org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel; /** * Detects Diablo JVM 1.5 (FreeBSD) * Note that Diablo JVM 1.6 is detected by default VisualVM implemntation * * @author Tomas Hurka */ public class DiabloJvmJvmstatModelProvider extends AbstractModelProvider { public JvmJvmstatModel createModelFor(Application app) { JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app); if (jvmstat != null) { String vmVersion = jvmstat.findByName("java.property.java.vm.version"); // NOI18N if (vmVersion != null) { if (vmVersion.startsWith("diablo-1.5.")) { // NOI18N // Diablo VM return new ExtendedJvmJvmstatModel(app, jvmstat); } } } return null; } } ================================================ FILE: plugins/extensions/src/org/graalvm/visualvm/modules/extensions/ExtendedJvmJvmstatModel.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.extensions; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.tools.jvmstat.JvmstatModel; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel; import org.graalvm.visualvm.tools.jvmstat.MonitoredValue; /** * * @author Tomas Hurka */ class ExtendedJvmJvmstatModel extends JvmJvmstatModel { private static final String PERM_GEN_PREFIX = "sun.gc.generation.2."; // NOI18N ExtendedJvmJvmstatModel(Application app,JvmstatModel stat) { super(app,stat); initMonitoredValues(); } private void initMonitoredValues() { loadedClasses = jvmstat.findMonitoredValueByName("java.cls.loadedClasses"); // NOI18N sharedLoadedClasses = jvmstat.findMonitoredValueByName("java.cls.sharedLoadedClasses"); // NOI18N sharedUnloadedClasses = jvmstat.findMonitoredValueByName("java.cls.sharedUnloadedClasses"); // NOI18N unloadedClasses = jvmstat.findMonitoredValueByName("java.cls.unloadedClasses"); // NOI18N threadsDaemon = jvmstat.findMonitoredValueByName("java.threads.daemon"); // NOI18N threadsLive = jvmstat.findMonitoredValueByName("java.threads.live"); // NOI18N threadsLivePeak = jvmstat.findMonitoredValueByName("java.threads.livePeak"); // NOI18N threadsStarted = jvmstat.findMonitoredValueByName("java.threads.started"); // NOI18N applicationTime = jvmstat.findMonitoredValueByName("sun.rt.applicationTime"); // NOI18N upTime = jvmstat.findMonitoredValueByName("sun.os.hrt.ticks"); // NOI18N MonitoredValue osFrequencyMon = jvmstat.findMonitoredValueByName("sun.os.hrt.frequency"); // NOI18N osFrequency = getLongValue(osFrequencyMon); genCapacity = jvmstat.findMonitoredValueByPattern("sun.gc.generation.[0-9]+.capacity"); // NOI18N genUsed = jvmstat.findMonitoredValueByPattern("sun.gc.generation.[0-9]+.space.[0-9]+.used"); // NOI18N genMaxCapacity=getGenerationSum(jvmstat.findMonitoredValueByPattern("sun.gc.generation.[0-9]+.maxCapacity")); // NOI18N } protected String getPermGenPrefix() { return PERM_GEN_PREFIX; } } ================================================ FILE: plugins/extensions/src/org/graalvm/visualvm/modules/extensions/Installer.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.extensions; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory; import org.openide.modules.ModuleInstall; /** * Manages a module's lifecycle. */ public class Installer extends ModuleInstall { @Override public void restored() { JvmJvmstatModelFactory factory = JvmJvmstatModelFactory.getDefault(); factory.registerProvider(new SapJvmJvmstatModelProvider()); factory.registerProvider(new DiabloJvmJvmstatModelProvider()); } } ================================================ FILE: plugins/extensions/src/org/graalvm/visualvm/modules/extensions/SapJvmJvmstatModelProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.extensions; import org.graalvm.visualvm.core.model.AbstractModelProvider; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.tools.jvmstat.JvmstatModel; import org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel; /** * Detects SAP JVM * @author Tomas Hurka */ public class SapJvmJvmstatModelProvider extends AbstractModelProvider { public JvmJvmstatModel createModelFor(Application app) { JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app); if (jvmstat != null) { String vmName = jvmstat.findByName("java.property.java.vm.name"); // NOI18N if (vmName != null && vmName.startsWith("SAP Java ")) { // NOI18N String vmVersion = jvmstat.findByName("java.property.java.vm.version"); // NOI18N if (vmVersion != null) { if (vmVersion.startsWith("5.1")) { // NOI18N // SAP VM return new ExtendedJvmJvmstatModel(app, jvmstat); } } } } return null; } } ================================================ FILE: plugins/glassfish/amx-api/DUAL_LICENSE.txt ================================================ LICENSE #1: The GNU General Public License (GPL) Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. One line to give the program's name and a brief idea of what it does. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. "CLASSPATH" EXCEPTION TO THE GPL VERSION 2 Certain source files distributed by Sun Microsystems, Inc. are subject to the following clarification and special exception to the GPL Version 2, but only where Sun has expressly included in the particular source file's header the words "Sun designates this particular file as subject to the "Classpath" exception as provided by Sun in the License file that accompanied this code." Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License Version 2 cover the whole combination. As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. *********************************************************** LICENSE #2: COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 1. Definitions. 1.1. "Contributor" means each individual or entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. 1.3. "Covered Software" means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. 1.4. "Executable" means the Covered Software in any form other than Source Code. 1.5. "Initial Developer" means the individual or entity that first makes Original Software available under this License. 1.6. "Larger Work" means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. 1.7. "License" means this document. 1.8. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means the Source Code and Executable form of any of the following: A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; B. Any new file that contains any part of the Original Software or previous Modification; or C. Any new file that is contributed or otherwise made available under the terms of this License. 1.10. "Original Software" means the Source Code and Executable form of computer software code that is originally released under this License. 1.11. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.12. "Source Code" means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. 1.13. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants. 2.1. The Initial Developer Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. 2.2. Contributor Grant. Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Availability of Source Code. Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. 3.2. Modifications. The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. 3.3. Required Notices. You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. 3.4. Application of Additional Terms. You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.5. Distribution of Executable Versions. You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.6. Larger Works. You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. 4. Versions of the License. 4.1. New Versions. Sun Microsystems, Inc. is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. 4.2. Effect of New Versions. You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. 4.3. Modified Versions. When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. 5. DISCLAIMER OF WARRANTY. COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 6. TERMINATION. 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as "Participant") alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. 7. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 8. U.S. GOVERNMENT END USERS. The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" (as that term is defined at 48 C.F.R. ¤ 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. 9. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. 10. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. *********************************************************** ================================================ FILE: plugins/glassfish/amx-api/build.xml ================================================ Builds, tests, and runs the project com.sun.appserv.management. ================================================ FILE: plugins/glassfish/amx-api/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: com.sun.appserv.management OpenIDE-Module-Localizing-Bundle: com/sun/appserv/management/Bundle.properties OpenIDE-Module-Specification-Version: 1.0 ================================================ FILE: plugins/glassfish/amx-api/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/glassfish/amx-api/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=f1bd27f3 build.xml.script.CRC32=2e75ad6e build.xml.stylesheet.CRC32=79c3b980 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=f1bd27f3 nbproject/build-impl.xml.script.CRC32=bbfe7d07 nbproject/build-impl.xml.stylesheet.CRC32=deb65f65 ================================================ FILE: plugins/glassfish/amx-api/nbproject/project.properties ================================================ # # Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. is.autoload=true license.file=${basedir}/DUAL_LICENSE.txt nbm.homepage=https://visualvm.github.io ================================================ FILE: plugins/glassfish/amx-api/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project com.sun.appserv.management com.sun.appserv.management com.sun.appserv.management.base com.sun.appserv.management.client com.sun.appserv.management.client.handler com.sun.appserv.management.client.prefs com.sun.appserv.management.config com.sun.appserv.management.deploy com.sun.appserv.management.ext.lb com.sun.appserv.management.ext.logging com.sun.appserv.management.ext.update com.sun.appserv.management.ext.wsmgmt com.sun.appserv.management.helper com.sun.appserv.management.j2ee com.sun.appserv.management.j2ee.statistics com.sun.appserv.management.monitor com.sun.appserv.management.monitor.statistics com.sun.appserv.management.util.j2ee com.sun.appserv.management.util.j2ee.stringifier com.sun.appserv.management.util.jmx com.sun.appserv.management.util.jmx.stringifier com.sun.appserv.management.util.misc com.sun.appserv.management.util.stringifier com.sun.enterprise.management.deploy javax.activation javax.annotation javax.annotation.security javax.ejb javax.ejb.spi javax.el javax.enterprise.deploy.model javax.enterprise.deploy.model.exceptions javax.enterprise.deploy.shared javax.enterprise.deploy.shared.factories javax.enterprise.deploy.spi javax.enterprise.deploy.spi.exceptions javax.enterprise.deploy.spi.factories javax.enterprise.deploy.spi.status javax.faces javax.faces.application javax.faces.component javax.faces.component.html javax.faces.context javax.faces.convert javax.faces.el javax.faces.event javax.faces.lifecycle javax.faces.model javax.faces.render javax.faces.validator javax.faces.webapp javax.interceptor javax.jms javax.jws javax.jws.soap javax.mail javax.mail.event javax.mail.internet javax.mail.search javax.mail.util javax.management.j2ee javax.management.j2ee.statistics javax.persistence javax.persistence.spi javax.resource javax.resource.cci javax.resource.spi javax.resource.spi.endpoint javax.resource.spi.security javax.resource.spi.work javax.security.jacc javax.servlet javax.servlet.http javax.servlet.jsp javax.servlet.jsp.el javax.servlet.jsp.jstl.core javax.servlet.jsp.jstl.fmt javax.servlet.jsp.jstl.sql javax.servlet.jsp.jstl.tlv javax.servlet.jsp.tagext javax.transaction javax.transaction.xa javax.xml.bind javax.xml.bind.annotation javax.xml.bind.annotation.adapters javax.xml.bind.attachment javax.xml.bind.helpers javax.xml.bind.util javax.xml.registry javax.xml.registry.infomodel javax.xml.registry.samples javax.xml.rpc javax.xml.rpc.encoding javax.xml.rpc.handler javax.xml.rpc.handler.soap javax.xml.rpc.holders javax.xml.rpc.server javax.xml.rpc.soap javax.xml.soap javax.xml.stream javax.xml.stream.events javax.xml.stream.util javax.xml.ws javax.xml.ws.handler javax.xml.ws.handler.soap javax.xml.ws.http javax.xml.ws.soap javax.xml.ws.spi javax.xml.ws.wsaddressing ext/amxapi.jar release/modules/ext/amxapi.jar ext/javaee.jar release/modules/ext/javaee.jar ================================================ FILE: plugins/glassfish/amx-api/nbproject/suite.properties ================================================ suite.dir=${basedir}/../.. ================================================ FILE: plugins/glassfish/amx-api/src/com/sun/appserv/management/Bundle.properties ================================================ # # Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Libraries OpenIDE-Module-Long-Description=\ GlassFish AMX API Library Wrapper OpenIDE-Module-Name=GlassFish AMX API OpenIDE-Module-Short-Description=GlassFish AMX API Library Wrapper ================================================ FILE: plugins/glassfish/build.xml ================================================ Builds, tests, and runs the project net.java.visualvm.modules.glassfish. ================================================ FILE: plugins/glassfish/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: net.java.visualvm.modules.glassfish OpenIDE-Module-Install: net/java/visualvm/modules/glassfish/Installer.class OpenIDE-Module-Localizing-Bundle: net/java/visualvm/modules/glassfish/Bundle.properties OpenIDE-Module-Specification-Version: 1.5 ================================================ FILE: plugins/glassfish/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/glassfish/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=a5d05ec0 build.xml.script.CRC32=42d55a6f build.xml.stylesheet.CRC32=79c3b980 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=a5d05ec0 nbproject/build-impl.xml.script.CRC32=3a954cd9 nbproject/build-impl.xml.stylesheet.CRC32=deb65f65 ================================================ FILE: plugins/glassfish/nbproject/project.properties ================================================ # # Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. javac.source=1.5 javac.compilerargs=-Xlint -Xlint:-serial cp.extra=${tools.jar} license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Jaroslav Bachorik project.license=GPLv2CPE ================================================ FILE: plugins/glassfish/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project net.java.visualvm.modules.glassfish com.sun.appserv.management 1.0 org.graalvm.visualvm.application 2 2.0 org.graalvm.visualvm.application.views 2 2.0 org.graalvm.visualvm.charts 2 2.0 org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.host 2 2.0 org.graalvm.visualvm.tools 2 2.0 org.graalvm.visualvm.uisupport 2 2.0 org.openide.dialogs 7.5.1 org.openide.modules 7.3.1 org.openide.util 9.8 org.openide.util.ui 9.8 ================================================ FILE: plugins/glassfish/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/Bundle.properties ================================================ # # Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Application Servers OpenIDE-Module-Long-Description=\ A sample plugin giving an overview of advanced monitoring capabilities of VisualVM. \n\ Enhances monitoring of GlassFish application server by adding specialized overview, new tab for monitoring HTTP Service and the ability to visually select and monitor any of the deployed web applications OpenIDE-Module-Name=VisualVM-Glassfish OpenIDE-Module-Short-Description=Enhaned monitoring of GlassFish application server ManagementTabContent.jLabel1.text=jLabel1 ManagementTabContent.jLabel2.text=jLabel2 ManagementTabContent.jLabel3.text=jLabel3 ManagementTabContent.jLabel4.text=jLabel4 DESCR_GlassFish=GlassFish instance (domain: {0}). GlassFish is an open source application server for the Java EE platform. ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishApplicationType.java ================================================ /* /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish; import org.graalvm.visualvm.application.type.ApplicationType; import org.openide.util.ImageUtilities; import java.awt.Image; /** * * @author Jaroslav Bachorik */ public abstract class GlassFishApplicationType extends ApplicationType { //~ Instance fields ---------------------------------------------------------------------------------------------------------- protected final String appPID; //~ Constructors ------------------------------------------------------------------------------------------------------------- public GlassFishApplicationType(int pid) { appPID = String.valueOf(pid); } //~ Methods ------------------------------------------------------------------------------------------------------------------ @Override public Image getIcon() { return ImageUtilities.loadImage("net/java/visualvm/modules/glassfish/resources/GlassFish.png", true); } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishApplicationTypeFactory.java ================================================ /* /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.application.jvm.JvmFactory; import org.graalvm.visualvm.application.type.ApplicationType; import org.graalvm.visualvm.application.type.ApplicationTypeFactory; import org.graalvm.visualvm.application.type.MainClassApplicationTypeFactory; /** * * @author Jaroslav Bachorik */ public class GlassFishApplicationTypeFactory extends MainClassApplicationTypeFactory { private final static GlassFishApplicationTypeFactory INSTANCE = new GlassFishApplicationTypeFactory(); private GlassFishApplicationTypeFactory() {} public static void initialize() { ApplicationTypeFactory.getDefault().registerProvider(INSTANCE); } public static void shutdown() { ApplicationTypeFactory.getDefault().unregisterProvider(INSTANCE); } @Override public ApplicationType createModelFor(Application app) { Jvm jvm = JvmFactory.getJVMFor(app); if (!jvm.isBasicInfoSupported()) return null; if (jvm.getMainClass() != null) return super.createModelFor(app); if (jvm.isGetSystemPropertiesSupported() && !jvm.getJvmArgs().contains("felix.fileinstall.dir")) { if (jvm.getSystemProperties().get("com.sun.aas.instanceName") != null) { return new GlassFishInstanceType(app, jvm); } } return null; } @Override public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) { if (!jvm.getJvmArgs().contains("felix.fileinstall.dir")) { if ("com.sun.enterprise.server.PELaunch".equals(mainClass)) { return new GlassFishInstanceType(app, jvm); } else if ("com.sun.enterprise.ee.nodeagent.NodeAgentMain".equals(mainClass)) { return new GlassFishNodeType(jvm, app.getPid()); } } return null; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishInstanceType.java ================================================ /* /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import java.awt.Image; import java.text.MessageFormat; import java.util.Properties; import java.util.logging.Logger; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; /** * * @author Jaroslav Bachorik */ public class GlassFishInstanceType extends GlassFishApplicationType { //~ Instance fields ---------------------------------------------------------------------------------------------------------- private final static Logger LOGGER = Logger.getLogger(GlassFishInstanceType.class.getName()); private final String description = NbBundle.getMessage(GlassFishInstanceType.class, "DESCR_GlassFish"); // NOI18N private String domainName = "UNKNOWN"; private final String typeName = "GlassFish/SJSAS"; private Jvm gfJvm; //~ Constructors ------------------------------------------------------------------------------------------------------------- public GlassFishInstanceType(Application app, Jvm jvm) { super(app.getPid()); init(app, jvm); } //~ Methods ------------------------------------------------------------------------------------------------------------------ @Override public String getDescription() { return MessageFormat.format(description, domainName); } @Override public Image getIcon() { Image icon = super.getIcon(); return ImageUtilities.mergeImages(icon, ImageUtilities.loadImage("net/java/visualvm/modules/glassfish/resources/instance_badge.png", true), 8, 8); } @Override public String getName() { return typeName; } @Override public String getVersion() { return "0"; } private void init(Application app, Jvm jvm) { try { if (jvm.isGetSystemPropertiesSupported()) { Properties props = jvm.getSystemProperties(); if (props != null) { domainName = props.getProperty("com.sun.aas.domainName", domainName); } } } catch (Exception ex) { LOGGER.throwing(GlassFishInstanceType.class.getName(), "init", ex); } } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishNodeType.java ================================================ /* /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish; import org.graalvm.visualvm.application.jvm.Jvm; import org.openide.util.ImageUtilities; import java.awt.Image; import java.text.MessageFormat; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * @author Jaroslav Bachorik */ public class GlassFishNodeType extends GlassFishApplicationType { //~ Instance fields ---------------------------------------------------------------------------------------------------------- private final String description = "(agent = {0})"; private final String typeName = "GlassFish/SJSAS Node (pid {0})"; private String nodeName = "UNKNOWN"; //~ Constructors ------------------------------------------------------------------------------------------------------------- public GlassFishNodeType(Jvm jvm, int pid) { super(pid); init(jvm); } //~ Methods ------------------------------------------------------------------------------------------------------------------ @Override public String getDescription() { return MessageFormat.format(description, nodeName); } @Override public Image getIcon() { Image icon = super.getIcon(); return ImageUtilities.mergeImages(icon, ImageUtilities.loadImage("net/java/visualvm/modules/glassfish/resources/node_badge.png", true), 8, 8); } @Override public String getName() { return MessageFormat.format(typeName, appPID); } @Override public String getVersion() { return "0"; } private void init(Jvm jvm) { Pattern pattern = Pattern.compile("-Dcom\\.sun\\.aas\\.instanceName=(.*?)\\s"); Matcher mtchr = pattern.matcher(jvm.getJvmArgs()); if (mtchr.find()) { nodeName = mtchr.group(1); } } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishOverviewPlugin.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish; import com.sun.appserv.management.DomainRoot; import com.sun.appserv.management.config.ConfigConfig; import com.sun.appserv.management.config.HTTPListenerConfig; import com.sun.appserv.management.config.HTTPServiceConfig; import com.sun.appserv.management.config.IIOPListenerConfig; import com.sun.appserv.management.config.IIOPServiceConfig; import com.sun.appserv.management.config.ModuleMonitoringLevelsConfig; import com.sun.appserv.management.config.SystemPropertiesAccess; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.ui.DataSourceViewPlugin; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.core.ui.components.DataViewComponent.DetailsView; import org.graalvm.visualvm.core.ui.components.ScrollableContainer; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import org.graalvm.visualvm.uisupport.HTMLTextArea; import javax.swing.event.HyperlinkEvent; import net.java.visualvm.modules.glassfish.jmx.AMXUtil; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import javax.swing.BorderFactory; import javax.swing.SwingWorker; import javax.swing.event.HyperlinkListener; import net.java.visualvm.modules.glassfish.jmx.JMXUtil; /** * * @author Jaroslav Bachorik */ public class GlassFishOverviewPlugin extends DataSourceViewPlugin { private JmxModel model = null; //~ Inner Classes ------------------------------------------------------------------------------------------------------------ private static class GlassfishOverviewPanel extends HTMLTextArea { //~ Instance fields ------------------------------------------------------------------------------------------------------ private DomainRoot domainRoot; private String serverName, configName; private JmxModel jmxModel; //~ Constructors --------------------------------------------------------------------------------------------------------- public GlassfishOverviewPanel(DomainRoot root, JmxModel jmx) { domainRoot = root; jmxModel = jmx; assert domainRoot != null && jmxModel != null; serverName = JMXUtil.getServerName(jmx); configName = JMXUtil.getServerConfig(jmx); assert serverName != null && configName != null; initComponents(); } private void initComponents() { setOpaque(true); setBorder(BorderFactory.createEmptyBorder()); addHyperlinkListener(new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { StringTokenizer st = new StringTokenizer(e.getDescription(), "#"); String service = st.nextToken(); String level = st.nextToken(); setMonitoringLevel(AMXUtil.getMonitoringConfig(jmxModel), service, cycleLevel(level)); setText(buildInfo()); } } }); new SwingWorker() { private String areaText = null; @Override protected Void doInBackground() throws Exception { areaText = buildInfo(); return null; } @Override protected void done() { if (areaText != null) setText(areaText); } }.execute(); } private Collection getHTTPPorts(HTTPServiceConfig config) { Map listeners = config.getHTTPListenerConfigMap(); Collection ports = new ArrayList(); for (String key : listeners.keySet()) { String port = listeners.get(key).getPort(); if (port.startsWith("$")) { port = resolveToken((port.substring(2, port.length() - 1))); } ports.add(port); } return ports; } private Collection getIIOPPorts(IIOPServiceConfig config) { //iiop ports Map iiopListeners = config.getIIOPListenerConfigMap(); Collection iports = new ArrayList(); for (String key : iiopListeners.keySet()) { String iport = iiopListeners.get(key).getPort(); if (iport.startsWith("$")) { iport = resolveToken((iport.substring(2, iport.length() - 1))); } iports.add(iport); } return iports; } private String getDomain() { String domain; domain = JMXUtil.getServerDomain(jmxModel); return domain != null ? domain : "General information"); sb.append("Server Name: ").append(serverName).append("
"); sb.append("Domain: ").append(getDomain()).append("
"); sb.append("Config Dir: ").append(JMXUtil.getServerConfigDir(jmxModel)).append("
"); sb.append("
"); sb.append("HTTP Port(s): "); Collection hports = getHTTPPorts(cc.getHTTPServiceConfig()); for (Iterator iter = hports.iterator(); iter.hasNext();) { sb.append(iter.next()); if (iter.hasNext()) { sb.append(","); } } sb.append("
"); sb.append("IIOP Port(s): "); Collection iports = getIIOPPorts(cc.getIIOPServiceConfig()); for (Iterator iter = iports.iterator(); iter.hasNext();) { sb.append(iter.next()); if (iter.hasNext()) { sb.append(","); } } sb.append("

"); String version = domainRoot.getJ2EEDomain().getJ2EEServerMap().get(serverName).getserverVersion(); sb.append("Installed Version: ").append(version).append("

"); ModuleMonitoringLevelsConfig monitoringConfig = AMXUtil.getMonitoringConfig(jmxModel); if (monitoringConfig != null) { sb.append("
"); sb.append("

Monitoring Configuration

"); sb.append(""); for(Map.Entry entry : monitoringConfig.getAllLevels().entrySet()) { String color; if (entry.getValue().toUpperCase().equals("OFF")) { color = "red"; } else if (entry.getValue().toUpperCase().equals("LOW")) { color = "yellow"; } else { color = "green"; } sb.append(""); sb.append(""); sb.append(""); sb.append(""); } sb.append("
").append(entry.getKey()).append(""); sb.append(""); sb.append(entry.getValue()).append("
"); } return sb.toString(); } private String resolveToken(String pn) { //For EE, the instance will have its own override System Properties value instead of using the one from config. if (AMXUtil.isEE(domainRoot)) { SystemPropertiesAccess sprops = domainRoot.getDomainConfig().getStandaloneServerConfigMap().get(serverName); if (sprops == null) { sprops = domainRoot.getDomainConfig().getClusteredServerConfigMap().get(serverName); } if (sprops != null) { if (sprops.existsSystemProperty(pn)) { return sprops.getSystemPropertyValue(pn); } } } ConfigConfig config = domainRoot.getDomainConfig().getConfigConfigMap().get(configName); return config.getSystemPropertyValue(pn); } private static String cycleLevel(String level) { if (level.toUpperCase().equals("OFF")) { return "LOW"; } else if (level.toUpperCase().equals("LOW")) { return "HIGH"; } else { return "OFF"; } } private static void setMonitoringLevel(ModuleMonitoringLevelsConfig config, String service, String level) { if (service.toUpperCase().equals("HTTPSERVICE")) { config.setHTTPService(level); } else if (service.toUpperCase().equals("CONNECTORSERVICE")) { config.setConnectorService(level); } else if (service.toUpperCase().equals("JDBCCONNECTIONPOOL")) { config.setJDBCConnectionPool(level); } else if (service.toUpperCase().equals("THREADPOOL")) { config.setThreadPool(level); } else if (service.toUpperCase().equals("ORB")) { config.setORB(level); } else if (service.toUpperCase().equals("CONNECTORCONNECTIONPOOL")) { config.setConnectorConnectionPool(level); } else if (service.toUpperCase().equals("JVM")) { config.setJVM(level); } else if (service.toUpperCase().equals("TRANSACTIONSERVICE")) { config.setTransactionService(level); } else if (service.toUpperCase().equals("WEBCONTAINER")) { config.setWebContainer(level); } else if (service.toUpperCase().equals("JMSSERVICE")) { config.setJMSService(level); } else if (service.toUpperCase().equals("EJBCONTAINER")) { config.setEJBContainer(level); } } } @Override public DetailsView createView(int position) { if (model == null) return null; if (position == DataViewComponent.TOP_RIGHT) { DomainRoot root = AMXUtil.getDomainRoot(model); if (root != null) { return new DataViewComponent.DetailsView("Application Server", null, 0, new ScrollableContainer(new GlassfishOverviewPanel(root, model)), null); } } return null; } public GlassFishOverviewPlugin(Application app) { super(app); model = JmxModelFactory.getJmxModelFor(app); } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishOverviewPluginProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.type.ApplicationTypeFactory; import org.graalvm.visualvm.application.views.ApplicationViewsSupport; import org.graalvm.visualvm.core.ui.DataSourceViewPlugin; import org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider; /** * Provides a basic overview of a GlassFish application server * configuration and capabilities * @author Jaroslav Bachorik */ public class GlassFishOverviewPluginProvider extends DataSourceViewPluginProvider { private final static class InstanceProvider { public static final GlassFishOverviewPluginProvider INSTANCE = new GlassFishOverviewPluginProvider(); } @Override protected DataSourceViewPlugin createPlugin(Application app) { return new GlassFishOverviewPlugin(app); } @Override protected boolean supportsPluginFor(Application app) { return (ApplicationTypeFactory.getApplicationTypeFor(app) instanceof GlassFishApplicationType); } public static void initialize() { ApplicationViewsSupport.sharedInstance().getOverviewView(). registerPluginProvider(InstanceProvider.INSTANCE); } public static void shutdown() { ApplicationViewsSupport.sharedInstance().getOverviewView(). unregisterPluginProvider(InstanceProvider.INSTANCE); } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/Installer.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish; import net.java.visualvm.modules.glassfish.datasource.GlassFishApplicationProvider; import net.java.visualvm.modules.glassfish.dataview.GlassFishApplicationViewProvider; import net.java.visualvm.modules.glassfish.datasource.GlassFishModelProvider; import net.java.visualvm.modules.glassfish.datasource.GlassFishDataSourceDescriptorProvider; import net.java.visualvm.modules.glassfish.datasource.GlassFishServletProvider; import net.java.visualvm.modules.glassfish.dataview.GlassFishServletViewProvider; import net.java.visualvm.modules.glassfish.dataview.GlassFishWebModuleViewProvider; import net.java.visualvm.modules.glassfish.jmx.GFJmxModelFactory; import org.openide.modules.ModuleInstall; /** * Manages a module's lifecycle. Remember that an installer is optional and * often not needed at all. */ public class Installer extends ModuleInstall { //~ Instance fields ---------------------------------------------------------------------------------------------------------- private GlassFishApplicationTypeFactory factory; //~ Methods ------------------------------------------------------------------------------------------------------------------ @Override public void restored() { GlassFishApplicationTypeFactory.initialize(); GlassFishApplicationViewProvider.initialize(); GlassFishModelProvider.initialize(); GlassFishServletProvider.initialize(); GlassFishWebModuleViewProvider.initialize(); GlassFishServletViewProvider.initialize(); GlassFishOverviewPluginProvider.initialize(); GlassFishDataSourceDescriptorProvider.initialize(); GlassFishApplicationProvider.initialize(); } @Override public void uninstalled() { GlassFishApplicationTypeFactory.shutdown(); GlassFishApplicationViewProvider.shutdown(); GlassFishModelProvider.shutdown(); GlassFishServletProvider.shutdown(); GlassFishWebModuleViewProvider.shutdown(); GlassFishServletViewProvider.shutdown(); GlassFishOverviewPluginProvider.shutdown(); GlassFishDataSourceDescriptorProvider.shutdown(); GlassFishApplicationProvider.shutdown(); super.uninstalled(); } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishApplication.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.datasource; /** * * @author Jaroslav Bachorik */ public abstract class GlassFishApplication extends GlassFishDataSource { private GlassFishModel glassFishRoot; private String name; private String objectName; public GlassFishApplication(String name, String objName, GlassFishModel gfRoot) { super(); this.name = name; this.glassFishRoot = gfRoot; this.objectName = objName; } public GlassFishModel getGlassFishRoot() { return glassFishRoot; } public String getName() { return name; } public String getObjectName() { return objectName; } abstract public void generateContents(); @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final GlassFishApplication other = (GlassFishApplication) obj; if (this.glassFishRoot != other.glassFishRoot && (this.glassFishRoot == null || !this.glassFishRoot.equals(other.glassFishRoot))) { return false; } if (this.objectName != other.objectName && (this.objectName == null || !this.objectName.equals(other.objectName))) { return false; } return true; } @Override public int hashCode() { int hash = 5; hash = 11 * hash + (this.glassFishRoot != null ? this.glassFishRoot.hashCode() : 0); hash = 11 * hash + (this.objectName != null ? this.objectName.hashCode() : 0); return hash; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishApplicationProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.datasource; import com.sun.appserv.management.DomainRoot; import com.sun.appserv.management.config.WebModuleConfig; import com.sun.appserv.management.j2ee.J2EETypes; import com.sun.appserv.management.monitor.ServerRootMonitor; import com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.datasource.DataSourceRepository; import org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor; import org.graalvm.visualvm.core.datasupport.DataChangeEvent; import org.graalvm.visualvm.core.datasupport.DataChangeListener; import org.graalvm.visualvm.core.datasupport.DataRemovedListener; import org.graalvm.visualvm.core.explorer.ExplorerExpansionListener; import org.graalvm.visualvm.core.explorer.ExplorerSupport; import org.graalvm.visualvm.core.scheduler.Quantum; import org.graalvm.visualvm.core.scheduler.ScheduledTask; import org.graalvm.visualvm.core.scheduler.Scheduler; import org.graalvm.visualvm.core.scheduler.SchedulerTask; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import net.java.visualvm.modules.glassfish.jmx.AMXUtil; import net.java.visualvm.modules.glassfish.jmx.JMXUtil; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; /** * * @author Jaroslav Bachorik */ public class GlassFishApplicationProvider implements DataChangeListener, DataRemovedListener, ExplorerExpansionListener { private static final GlassFishApplicationProvider INSTANCE = new GlassFishApplicationProvider(); private final Map taskMap = new HashMap(); private static class LazyLoadingSource extends GlassFishDataSource { private String message; private GlassFishModel parent; public LazyLoadingSource(String message, GlassFishModel parent) { this.message = message; this.parent = parent; } @Override public DataSourceDescriptor getDescriptor() { return new DataSourceDescriptor(this) { @Override public int getAutoExpansionPolicy() { return EXPAND_NEVER; } @Override public String getName() { return message; } }; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final LazyLoadingSource other = (LazyLoadingSource) obj; if (this.message != other.message && (this.message == null || !this.message.equals(other.message))) { return false; } if (this.parent != other.parent && (this.parent == null || !this.parent.equals(other.parent))) { return false; } return true; } @Override public int hashCode() { int hash = 7; hash = 19 * hash + (this.message != null ? this.message.hashCode() : 0); hash = 19 * hash + (this.parent != null ? this.parent.hashCode() : 0); return hash; } } private class DiscoveryTask implements SchedulerTask { final private AtomicBoolean isProcessing = new AtomicBoolean(false); final private AtomicBoolean beenNotified = new AtomicBoolean(false); private GlassFishModel model; public DiscoveryTask(GlassFishModel model) { this.model = model; } public void onSchedule(long timeStamp) { if (!isProcessing.compareAndSet(false, true)) { return; } try { JmxModel jmx = JmxModelFactory.getJmxModelFor(model.getApplication()); if ((jmx == null || jmx.getConnectionState() == JmxModel.ConnectionState.DISCONNECTED)){ if (beenNotified.compareAndSet(false, true)) { NotifyDescriptor nd = new NotifyDescriptor.Message("Cannot establish JMX connection", NotifyDescriptor.ERROR_MESSAGE); DialogDisplayer.getDefault().notifyLater(nd); model.setVisible(false); } return; } if (jmx.getConnectionState() != JmxModel.ConnectionState.CONNECTED) { model.setVisible(true); return; } DomainRoot dr = AMXUtil.getDomainRoot(jmx); if (dr == null || !dr.getAMXReady()) { return; } String serverName = JMXUtil.getServerName(jmx); if (serverName == null) { return; } ServerRootMonitor srm = dr.getMonitoringRoot().getServerRootMonitorMap().get(serverName); Map map = dr.getDomainConfig().getWebModuleConfigMap(); Map contextRootMap = new HashMap(); for (Map.Entry cfgEntry : map.entrySet()) { String contextRoot = cfgEntry.getValue().getContextRoot(); if (!contextRoot.startsWith("/")) { contextRoot = "/" + contextRoot; } contextRootMap.put(contextRoot, cfgEntry.getKey()); } Set currentApps = new HashSet(); for (Map.Entry virtMonitorEntry : srm.getWebModuleVirtualServerMonitorMap().entrySet()) { String objectName = JMXUtil.getObjectName(J2EETypes.WEB_MODULE, virtMonitorEntry.getKey(), jmx); String moduleName = JMXUtil.getWebModuleName(objectName, jmx, contextRootMap); String appName = JMXUtil.getJ2EEAppName(objectName); if (moduleName == null || moduleName.length() == 0) { continue; } GlassFishWebModule webModule = new GlassFishWebModule(appName != null ? (moduleName + " (in " + appName + ")") : moduleName, objectName, virtMonitorEntry.getValue(), model); currentApps.add(webModule); } Set toRemoveApps = new HashSet(model.getRepository().getDataSources(GlassFishDataSource.class)); Set toAdd = new HashSet(currentApps); toRemoveApps.removeAll(currentApps); toAdd.removeAll(model.getRepository().getDataSources()); Set lazy = model.getRepository().getDataSources(LazyLoadingSource.class); Set toRemove = new HashSet(toRemoveApps); toRemove.addAll(lazy); if (currentApps.size() == 0) { LazyLoadingSource unavailable = new LazyLoadingSource("Unavailable", model); toAdd.add(unavailable); toRemove.remove(unavailable); } toAdd.removeAll(lazy); if (toAdd.size() > 0 || toRemove.size() > 0) { model.getRepository().addDataSources(toAdd); model.getRepository().removeDataSources(toRemove); // model.getRepository().updateDataSources(toAdd, toRemove); } } catch (UndeclaredThrowableException e) { // this is caused by disappearing of the underlying JMX connection // just ignore it } finally { isProcessing.set(false); } } } public void dataChanged(DataChangeEvent event) { if (event.getAdded().isEmpty() && event.getRemoved().isEmpty()) { addModels(event.getCurrent()); } else { addModels(event.getAdded()); removeModels(event.getRemoved()); } } private void addModels(Set models) { for (GlassFishModel model : models) { GlassFishDataSource lazyDS = new LazyLoadingSource("Please wait", model); model.getRepository().addDataSource(lazyDS); ScheduledTask task = Scheduler.sharedInstance().schedule(new DiscoveryTask(model), Quantum.SUSPENDED); taskMap.put(model, task); } } private void removeModels(Set models) { for (GlassFishModel model : models) { // removing the reference to the ScheduledTask practically unschedules the task Scheduler.sharedInstance().unschedule(taskMap.remove(model)); Set roots = model.getRepository().getDataSources(GlassFishApplication.class); model.getRepository().removeDataSources(roots); } } public void dataRemoved(GlassFishModel model) { // removing the reference to the ScheduledTask practically unschedules the task Scheduler.sharedInstance().unschedule(taskMap.remove(model)); Set roots = model.getRepository().getDataSources(GlassFishApplication.class); model.getRepository().removeDataSources(roots); } public static void initialize() { DataSourceRepository.sharedInstance().addDataChangeListener(INSTANCE, GlassFishModel.class); ExplorerSupport.sharedInstance().addExpansionListener(INSTANCE); } public static void shutdown() { DataSourceRepository.sharedInstance().removeDataChangeListener(INSTANCE); ExplorerSupport.sharedInstance().removeExpansionListener(INSTANCE); } public void dataSourceCollapsed(DataSource source) { // do nothing } public void dataSourceExpanded(DataSource source) { if (source instanceof GlassFishModel) { if (taskMap.containsKey(source)) { taskMap.get(source).setInterval(Quantum.seconds(3)); } } } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishDataSource.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.datasource; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor; /** * * @author Jaroslav Bachorik */ public abstract class GlassFishDataSource extends DataSource { public GlassFishDataSource() { this(null); } public GlassFishDataSource(DataSource master) { super(master); } abstract public DataSourceDescriptor getDescriptor(); } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishDataSourceDescriptorProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.datasource; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor; import org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory; import org.graalvm.visualvm.core.model.AbstractModelProvider; /** * * @author Jaroslav Bachorik */ public class GlassFishDataSourceDescriptorProvider extends AbstractModelProvider { final private static GlassFishDataSourceDescriptorProvider INSTANCE = new GlassFishDataSourceDescriptorProvider(); private GlassFishDataSourceDescriptorProvider() {} @Override public DataSourceDescriptor createModelFor(DataSource glassFishDS) { if (glassFishDS instanceof GlassFishDataSource) { return ((GlassFishDataSource)glassFishDS).getDescriptor(); } return null; } public static void initialize() { DataSourceDescriptorFactory.getDefault().registerProvider(INSTANCE); } public static void shutdown() { DataSourceDescriptorFactory.getDefault().unregisterProvider(INSTANCE); } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishModel.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.datasource; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor; import java.awt.Image; /** * * @author Jaroslav Bachorik */ public class GlassFishModel extends GlassFishDataSource { private Application application; private final DataSourceDescriptor descriptor = new DataSourceDescriptor(this) { @Override public Image getIcon() { return null; } @Override public String getName() { return "Model"; } @Override public String getDescription() { return "GlassFish/SJSAS Logical Model"; } @Override public int getAutoExpansionPolicy() { return EXPAND_NEVER; } }; public GlassFishModel(Application app) { super(); application = app; } public Application getApplication() { return application; } @Override public DataSourceDescriptor getDescriptor() { return descriptor; } } // GlassFishWebModule module = new GlassFishWebModule(appName != null ? (moduleName + " (in " + appName + ")") : moduleName, objectName, virtMonitorEntry.getValue(), root); // registerDataSource(module); // root.getRepository().addDataSource(module); ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishModelProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.datasource; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.type.ApplicationTypeFactory; import org.graalvm.visualvm.core.datasource.DataSourceRepository; import org.graalvm.visualvm.core.datasupport.DataChangeEvent; import org.graalvm.visualvm.core.datasupport.DataChangeListener; import org.graalvm.visualvm.core.datasupport.DataRemovedListener; import java.util.Set; import net.java.visualvm.modules.glassfish.GlassFishApplicationType; import org.openide.util.RequestProcessor; /** * * @author Jaroslav Bachorik */ public class GlassFishModelProvider implements DataChangeListener, DataRemovedListener { //~ Static fields/initializers ----------------------------------------------------------------------------------------------- private static final GlassFishModelProvider INSTANCE = new GlassFishModelProvider(); private final DataRemovedListener removalListener = new DataRemovedListener() { public void dataRemoved(Application app) { processFinishedApplication(app); } }; private GlassFishModelProvider() { } //~ Methods ------------------------------------------------------------------------------------------------------------------ public void dataChanged(DataChangeEvent event) { if (event.getAdded().isEmpty() && event.getRemoved().isEmpty()) { // Initial event to deliver DataSources already created by the provider before registering to it as a listener // NOTE: already existing hosts are treated as new for this provider Set newApplications = event.getCurrent(); for (Application app : newApplications) { processNewApplication(app); } } else { // Real delta event Set newApplications = event.getAdded(); for (Application app : newApplications) { processNewApplication(app); } } } public static void initialize() { DataSourceRepository.sharedInstance().addDataChangeListener(INSTANCE, Application.class); } public static void shutdown() { DataSourceRepository.sharedInstance().removeDataChangeListener(INSTANCE); } public void dataRemoved(Application application) { processFinishedApplication(application); } private void processFinishedApplication(Application app) { // TODO: remove listener!!! Set roots = app.getRepository().getDataSources(GlassFishModel.class); app.getRepository().removeDataSources(roots); } private void processNewApplication(final Application app) { if (ApplicationTypeFactory.getApplicationTypeFor(app) instanceof GlassFishApplicationType) { RequestProcessor.getDefault().post(new Runnable() { public void run() { GlassFishModel gfm = new GlassFishModel(app); app.getRepository().addDataSource(gfm); app.notifyWhenRemoved(removalListener); } }, 1500); } } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishServlet.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.datasource; import com.sun.appserv.management.monitor.ServletMonitor; import org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor; import java.awt.Image; import org.openide.util.ImageUtilities; /** * * @author Jaroslav Bachorik */ public class GlassFishServlet extends GlassFishDataSource { private static final Image NODE_ICON = ImageUtilities.loadImage("net/java/visualvm/modules/glassfish/resources/servlet_icon.png", true); private ServletMonitor monitor; private String name; private final DataSourceDescriptor descriptor = new DataSourceDescriptor(this) { @Override public Image getIcon() { return NODE_ICON; } @Override public String getName() { return name; } @Override public String getDescription() { return null; } // @Override // public int getAutoExpansionPolicy() { // return DataSourceDescriptor.EXPAND_NEVER; // } }; public GlassFishServlet(String name, GlassFishWebModule master, ServletMonitor monitor) { super(master); this.monitor = monitor; this.name = name; } public ServletMonitor getMonitor() { return monitor; } @Override public DataSourceDescriptor getDescriptor() { return descriptor; } public String getName() { return name; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishServletProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.datasource; import com.sun.appserv.management.monitor.ServletMonitor; import org.graalvm.visualvm.core.datasource.DataSourceRepository; import org.graalvm.visualvm.core.datasupport.DataChangeEvent; import org.graalvm.visualvm.core.datasupport.DataChangeListener; import org.graalvm.visualvm.core.datasupport.DataRemovedListener; import java.util.Map; import java.util.Set; /** * * @author Jaroslav Bachorik */ public class GlassFishServletProvider implements DataChangeListener, DataRemovedListener { private final static GlassFishServletProvider INSTANCE = new GlassFishServletProvider(); private GlassFishServletProvider() {} //~ Methods ------------------------------------------------------------------------------------------------------------------ public void dataChanged(DataChangeEvent event) { if (event.getAdded().isEmpty() && event.getRemoved().isEmpty()) { // Initial event to deliver DataSources already created by the provider before registering to it as a listener // NOTE: already existing hosts are treated as new for this provider Set newModules = event.getCurrent(); for (GlassFishWebModule module : newModules) { processNewWebModule(module); } } else { // Real delta event Set newModules = event.getAdded(); for (GlassFishWebModule module : newModules) { processNewWebModule(module); } } } public static void initialize() { DataSourceRepository.sharedInstance().addDataChangeListener(INSTANCE, GlassFishWebModule.class); } public static void shutdown() { DataSourceRepository.sharedInstance().removeDataChangeListener(INSTANCE); } public void dataRemoved(GlassFishWebModule module) { processFinishedModule(module); } private void processFinishedModule(GlassFishWebModule module) { // TODO: remove listener!!! Set monitoredServlets = module.getRepository().getDataSources(GlassFishServlet.class); module.getRepository().removeDataSources(monitoredServlets); } private void processNewWebModule(final GlassFishWebModule module) { for (Map.Entry monitorEntry : module.getMonitor().getServletMonitorMap().entrySet()) { GlassFishServlet servlet = new GlassFishServlet(monitorEntry.getKey(), module, monitorEntry.getValue()); module.getRepository().addDataSource(servlet); } module.notifyWhenRemoved(this); } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishWebModule.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.datasource; import com.sun.appserv.management.monitor.ServletMonitor; import com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor; import org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor; import java.awt.Image; import java.util.Map; import org.openide.util.ImageUtilities; /** * * @author Jaroslav Bachorik */ public class GlassFishWebModule extends GlassFishApplication { private static final Image NODE_ICON = ImageUtilities.loadImage("net/java/visualvm/modules/glassfish/resources/application.png", true); private WebModuleVirtualServerMonitor monitor; private final DataSourceDescriptor descriptor = new DataSourceDescriptor(this) { @Override public Image getIcon() { return NODE_ICON; } @Override public String getName() { return GlassFishWebModule.this.getName(); } @Override public String getDescription() { return null; } @Override public int getAutoExpansionPolicy() { return DataSourceDescriptor.EXPAND_NEVER; } }; public GlassFishWebModule(String name, String objName, WebModuleVirtualServerMonitor monitor, GlassFishModel gfRoot) { super(name, objName, gfRoot); this.monitor = monitor; } public WebModuleVirtualServerMonitor getMonitor() { return monitor; } @Override public void generateContents() { for(Map.Entry monitorEntry : monitor.getServletMonitorMap().entrySet()) { GlassFishServlet servlet = new GlassFishServlet(monitorEntry.getKey(), this, monitorEntry.getValue()); getOwner().getRepository().addDataSource(servlet); } } @Override public DataSourceDescriptor getDescriptor() { return descriptor; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/AbstractStatsTableModel.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.dataview; import com.sun.appserv.management.monitor.MonitoringStats; import org.graalvm.visualvm.core.scheduler.Quantum; import org.graalvm.visualvm.core.scheduler.ScheduledTask; import org.graalvm.visualvm.core.scheduler.Scheduler; import org.graalvm.visualvm.core.scheduler.SchedulerTask; import java.lang.reflect.UndeclaredThrowableException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.j2ee.statistics.CountStatistic; import javax.management.j2ee.statistics.Statistic; import javax.management.j2ee.statistics.Stats; import javax.management.j2ee.statistics.TimeStatistic; import javax.swing.table.AbstractTableModel; import net.java.visualvm.modules.glassfish.util.Touple; /** * * @author Jaroslav Bachorik */ public abstract class AbstractStatsTableModel extends AbstractTableModel { final protected PM monitor; private ScheduledTask refresh; private final AtomicBoolean columnsInitialized = new AtomicBoolean(false); private final List> statsList = new ArrayList>(); private String[] columnNames; public AbstractStatsTableModel(PM aMonitor, Quantum refreshInterval) { super(); monitor = aMonitor; refresh = Scheduler.sharedInstance().schedule(new SchedulerTask() { public void onSchedule(long timeStamp) { try { synchronized (statsList) { statsList.clear(); for (Map.Entry monitor : getMonitorMap().entrySet()) { setColumnModel(monitor.getValue()); S stats = getStats(monitor.getValue()); if (!isDisplayable(stats)) { continue; } statsList.add(new Touple(monitor.getKey(), stats)); } fireTableDataChanged(); } } catch (Exception e) { if (!(e instanceof UndeclaredThrowableException)) { Logger.getLogger(AbstractStatsTableModel.class.getName()).log(Level.INFO,"onSchedule",e); } else { Scheduler.sharedInstance().unschedule(refresh); refresh = null; } } } }, refreshInterval, true); } abstract protected Map getMonitorMap(); abstract protected S getStats(M monitor); abstract protected boolean isDisplayable(S stats); private void setColumnModel(M monitor) { if (columnsInitialized.compareAndSet(false, true)) { columnNames = monitor.getStatisticNames(); } } public int getColumnCount() { if (columnsInitialized.get()) { return columnNames.length; } else { return 0; } } public int getRowCount() { synchronized (statsList) { return statsList.size(); } } public Object getValueAt(int rowIndex, int columnIndex) { Touple entry; synchronized (statsList) { entry = statsList.get(rowIndex); } switch (columnIndex) { case 0: { return entry.getX(); } default: { String name = columnNames[columnIndex - 1]; Statistic stat = entry.getY().getStatistic(name); if (stat instanceof CountStatistic) { return ((CountStatistic) stat).getCount(); } else if (stat instanceof TimeStatistic) { TimeStatistic ts = (TimeStatistic) stat; return ts.getCount() != 0 ? (double) ts.getTotalTime() / (double) ts.getCount() : 0.0; } return stat; } } } @Override public String getColumnName(int column) { if (columnsInitialized.get()) { switch (column) { case 0: { return "Name"; } default: { return columnNames[column - 1]; } } } else { return super.getColumnName(column); } } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/Bundle.properties ================================================ WebModuleViewPanel.jPanel1.border.title=Sessions WebModuleViewPanel.labelCurrent.text=Active Current WebModuleViewPanel.labelMax.text=Active Max WebModuleViewPanel.labelPassivated.text=Passivated WebModuleViewPanel.labelCreated.text=Created WebModuleViewPanel.labelExpired.text=Expired WebModuleViewPanel.labelRejected.text=Rejected WebModuleViewPanel.valueCurrent.text=0 WebModuleViewPanel.valueMax.text=0 WebModuleViewPanel.valuePassivated.text=0 WebModuleViewPanel.valueCreated.text=0 WebModuleViewPanel.valueExpired.text=0 WebModuleViewPanel.valueRejected.text=0 WebModuleViewPanel.jPanel4.border.title=JSPs WebModuleViewPanel.labelJspCount.text=Count WebModuleViewPanel.labelJspErrors.text=Errors WebModuleViewPanel.valueJspCount.text=0 WebModuleViewPanel.valueJspErrors.text=0 ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/GlassFishApplicationViewProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.dataview; import com.sun.appserv.management.DomainRoot; import com.sun.appserv.management.config.ModuleMonitoringLevelValues; import com.sun.appserv.management.config.ModuleMonitoringLevelsConfig; import com.sun.appserv.management.monitor.HTTPServiceMonitor; import com.sun.appserv.management.monitor.ServerRootMonitor; import com.sun.appserv.management.monitor.TransactionServiceMonitor; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.type.ApplicationTypeFactory; import org.graalvm.visualvm.core.snapshot.Snapshot; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.DataSourceViewProvider; import org.graalvm.visualvm.core.ui.DataSourceViewsManager; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import net.java.visualvm.modules.glassfish.GlassFishApplicationType; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import net.java.visualvm.modules.glassfish.jmx.AMXUtil; import net.java.visualvm.modules.glassfish.jmx.JMXUtil; /** * * @author Jaroslav Bachorik */ public class GlassFishApplicationViewProvider extends DataSourceViewProvider { private final static GlassFishApplicationViewProvider INSTANCE = new GlassFishApplicationViewProvider(); private final static Logger LOGGER = Logger.getLogger(GlassFishApplicationViewProvider.class.getName()); private final Map httpServiceViewMap = new HashMap(); private final Map transServiceViewMap = new HashMap(); private GlassFishApplicationViewProvider() { } @Override protected DataSourceView createView(Application app) { final JmxModel model = JmxModelFactory.getJmxModelFor(app); if (model == null) { return null; } DomainRoot dr = AMXUtil.getDomainRoot(model); if (dr == null) { return null; } final Map serverMonitors = dr.getMonitoringRoot().getServerRootMonitorMap(); final String serverName = JMXUtil.getServerName(model); if (serverMonitors.get(serverName) == null) { return null; } HTTPServiceMonitor httpMonitor = serverMonitors.get(serverName).getHTTPServiceMonitor(); ModuleMonitoringLevelsConfig monitorConfig = AMXUtil.getMonitoringConfig(model); if (!monitorConfig.getHTTPService().equals(ModuleMonitoringLevelValues.OFF)) { if (httpMonitor != null) { return getHTTPServiceView(app, httpMonitor); } } return null; } @Override protected boolean supportsViewFor(Application app) { if (!(ApplicationTypeFactory.getApplicationTypeFor(app) instanceof GlassFishApplicationType)) return false; final JmxModel model = JmxModelFactory.getJmxModelFor(app); if (model == null) { return false; } DomainRoot dr = AMXUtil.getDomainRoot(model); if (dr == null) { return false; } final Map serverMonitors = dr.getMonitoringRoot().getServerRootMonitorMap(); final String serverName = JMXUtil.getServerName(model); if (serverMonitors.get(serverName) == null) { return false; } HTTPServiceMonitor httpMonitor = serverMonitors.get(serverName).getHTTPServiceMonitor(); ModuleMonitoringLevelsConfig monitorConfig = AMXUtil.getMonitoringConfig(model); if (!monitorConfig.getHTTPService().equals(ModuleMonitoringLevelValues.OFF)) { return httpMonitor != null; } return false; } //~ Methods ------------------------------------------------------------------------------------------------------------------ // @Override // public Set getViews(final Application application) { // ApplicationType at = ApplicationTypeFactory.getApplicationTypeFor(application); // if (!(at instanceof GlassFishApplicationType)) { // return Collections.EMPTY_SET; // } // // final JmxModel model = JmxModelFactory.getJmxModelFor(application); // if (model == null) { // return Collections.EMPTY_SET; // } // // DomainRoot dr = AMXUtil.getDomainRoot(model); // if (dr == null) { // return Collections.EMPTY_SET; // } // // try { // final Map serverMonitors = dr.getMonitoringRoot().getServerRootMonitorMap(); // final String serverName = JMXUtil.getServerName(model); // // if (serverMonitors.get(serverName) == null) { // return Collections.EMPTY_SET; // } // // return new HashSet() { // // { // ModuleMonitoringLevelsConfig monitorConfig = AMXUtil.getMonitoringConfig(model); // if (!monitorConfig.getHTTPService().equals(ModuleMonitoringLevelValues.OFF)) { // HTTPServiceMonitor httpMonitor = serverMonitors.get(serverName).getHTTPServiceMonitor(); // if (httpMonitor != null) { // add(getHTTPServiceView(application, httpMonitor)); // } // } // if (!monitorConfig.getHTTPService().equals(ModuleMonitoringLevelValues.OFF)) { // TransactionServiceMonitor transMonitor = serverMonitors.get(serverName).getTransactionServiceMonitor(); // if (transMonitor != null) { // add(getTransactionServiceView(application, transMonitor)); // } // } // } // }; // } catch (Exception e) { // LOGGER.throwing(GlassFishApplicationViewProvider.class.getName(), "getViews", e); // } // // return Collections.EMPTY_SET; // } private HTTPServiceView getHTTPServiceView(Application app, HTTPServiceMonitor monitor) { synchronized (httpServiceViewMap) { if (httpServiceViewMap.containsKey(app)) { return httpServiceViewMap.get(app); } else { HTTPServiceView view = new HTTPServiceView(app, monitor); httpServiceViewMap.put(app, view); return view; } } } private TransactionServiceView getTransactionServiceView(Application app, TransactionServiceMonitor monitor) { synchronized (transServiceViewMap) { if (transServiceViewMap.containsKey(app)) { return transServiceViewMap.get(app); } else { TransactionServiceView view = new TransactionServiceView(app, monitor); transServiceViewMap.put(app, view); return view; } } } public static void initialize() { DataSourceViewsManager.sharedInstance().addViewProvider(INSTANCE, Application.class); } public static void shutdown() { DataSourceViewsManager.sharedInstance().removeViewProvider(INSTANCE); INSTANCE.httpServiceViewMap.clear(); INSTANCE.transServiceViewMap.clear(); } public boolean supportsViewsFor(Application dataSource) { return (ApplicationTypeFactory.getApplicationTypeFor(dataSource) instanceof GlassFishApplicationType); } public void saveViews(Application app, Snapshot snapshot) { // TODO implement later } public boolean supportsSaveViewsFor(Application app) { return false; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/GlassFishServletViewProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.dataview; import com.sun.appserv.management.monitor.ServletMonitor; import com.sun.appserv.management.monitor.statistics.AltServletStats; import org.graalvm.visualvm.charts.ChartFactory; import org.graalvm.visualvm.charts.SimpleXYChartDescriptor; import org.graalvm.visualvm.charts.SimpleXYChartSupport; import org.graalvm.visualvm.core.scheduler.Quantum; import org.graalvm.visualvm.core.scheduler.ScheduledTask; import org.graalvm.visualvm.core.scheduler.Scheduler; import org.graalvm.visualvm.core.scheduler.SchedulerTask; import org.graalvm.visualvm.core.snapshot.Snapshot; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.DataSourceViewProvider; import org.graalvm.visualvm.core.ui.DataSourceViewsManager; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.uisupport.HTMLTextArea; import java.lang.reflect.UndeclaredThrowableException; import net.java.visualvm.modules.glassfish.datasource.GlassFishServlet; import org.openide.util.ImageUtilities; import java.awt.BorderLayout; import java.awt.Image; import java.util.HashMap; import java.util.Map; import javax.swing.JPanel; /** * * @author Jaroslav Bachorik */ public class GlassFishServletViewProvider extends DataSourceViewProvider { private final static GlassFishServletViewProvider INSTANCE = new GlassFishServletViewProvider(); private final Map viewMap = new HashMap(); //~ Inner Classes ------------------------------------------------------------------------------------------------------------ private static class GlassfishServletView extends DataSourceView { //~ Static fields/initializers ------------------------------------------------------------------------------------------- private static final Image NODE_ICON = ImageUtilities.loadImage("net/java/visualvm/modules/glassfish/resources/servlet_icon.png", true); //~ Instance fields ------------------------------------------------------------------------------------------------------ private SimpleXYChartSupport reqsChart; private SimpleXYChartSupport timesChart; private DataViewComponent dvc; private GlassFishServlet servlet; private ScheduledTask refreshTask; //~ Constructors --------------------------------------------------------------------------------------------------------- public GlassfishServletView(GlassFishServlet servlet) { super(servlet, servlet.getName(), NODE_ICON, 0, true); this.servlet = servlet; HTMLTextArea generalDataArea = new HTMLTextArea(); JPanel chartTimesPanel = new JPanel(new BorderLayout()); chartTimesPanel.setOpaque(false); SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500); desc.addLineItems("Average Time","Maximum Time"); timesChart = ChartFactory.createSimpleXYChart(desc); chartTimesPanel.add(timesChart.getChart(), BorderLayout.CENTER); JPanel chartReqsPanel = new JPanel(new BorderLayout()); chartReqsPanel.setOpaque(false); desc = SimpleXYChartDescriptor.decimal(10, false, 500); desc.addLineItems("Request Count","Error Count"); reqsChart = ChartFactory.createSimpleXYChart(desc); chartReqsPanel.add(reqsChart.getChart(), BorderLayout.CENTER); DataViewComponent.MasterView masterView = new DataViewComponent.MasterView("Overview", null, generalDataArea); DataViewComponent.MasterViewConfiguration masterConfiguration = new DataViewComponent.MasterViewConfiguration(false); dvc = new DataViewComponent(masterView, masterConfiguration); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("Time Profile", true), DataViewComponent.TOP_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("Time Profile", null, 10, chartTimesPanel, null), DataViewComponent.TOP_LEFT); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("Requests", true), DataViewComponent.BOTTOM_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("Requests", null, 10, chartReqsPanel, null), DataViewComponent.BOTTOM_LEFT); refreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() { public void onSchedule(long timeStamp) { try { refreshData(timeStamp); } catch (Exception e) { if (!(e instanceof UndeclaredThrowableException)) { System.out.println("Error: "+e.getMessage()); e.printStackTrace(); } else { Scheduler.sharedInstance().unschedule(refreshTask); refreshTask = null; } } } }, Quantum.seconds(3)); } //~ Methods -------------------------------------------------------------------------------------------------------------- @Override public DataViewComponent createComponent() { return dvc; } private void refreshData(long sampleTime) { ServletMonitor monitor = servlet.getMonitor(); AltServletStats stats = monitor.getAltServletStats(); timesChart.addValues(sampleTime, new long[] { Math.round((double) stats.getProcessingTime().getCount() / (double) stats.getRequestCount() .getCount()), stats.getMaxTime().getCount() }); reqsChart.addValues(sampleTime, new long[] { stats.getRequestCount().getCount(), stats.getErrorCount().getCount() }); } } private GlassFishServletViewProvider() {} @Override protected DataSourceView createView(GlassFishServlet servlet) { return new GlassfishServletView(servlet); } @Override protected boolean supportsViewFor(GlassFishServlet servlet) { return true; } //~ Methods ------------------------------------------------------------------------------------------------------------------ public static void initialize() { DataSourceViewsManager.sharedInstance().addViewProvider(INSTANCE, GlassFishServlet.class); } public static void shutdown() { DataSourceViewsManager.sharedInstance().removeViewProvider(INSTANCE); INSTANCE.viewMap.clear(); } public boolean supportsViewsFor(GlassFishServlet dataSource) { return true; } public void saveViews(GlassFishServlet servlet, Snapshot snapshot) { // TODO implement later } public boolean supportsSaveViewsFor(GlassFishServlet servlet) { return false; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/GlassFishWebModuleViewProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.dataview; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import java.util.logging.Level; import javax.management.AttributeNotFoundException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MalformedObjectNameException; import javax.management.ReflectionException; import net.java.visualvm.modules.glassfish.ui.StatsTable; import com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor; import com.sun.appserv.management.monitor.statistics.WebModuleVirtualServerStats; import org.graalvm.visualvm.charts.ChartFactory; import org.graalvm.visualvm.charts.SimpleXYChartDescriptor; import org.graalvm.visualvm.charts.SimpleXYChartSupport; import org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory; import org.graalvm.visualvm.core.scheduler.Quantum; import org.graalvm.visualvm.core.scheduler.ScheduledTask; import org.graalvm.visualvm.core.scheduler.Scheduler; import org.graalvm.visualvm.core.scheduler.SchedulerTask; import org.graalvm.visualvm.core.ui.DataSourceWindowManager; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.DataSourceViewProvider; import org.graalvm.visualvm.core.ui.DataSourceViewsManager; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import org.graalvm.visualvm.uisupport.HTMLLabel; import org.graalvm.visualvm.uisupport.HTMLTextArea; import net.java.visualvm.modules.glassfish.datasource.GlassFishWebModule; import org.openide.util.ImageUtilities; import java.awt.BorderLayout; import java.awt.Image; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.RowSorter; import javax.swing.table.TableModel; import javax.swing.table.TableRowSorter; /** * * @author Jaroslav Bachorik */ public class GlassFishWebModuleViewProvider extends DataSourceViewProvider { private final static GlassFishWebModuleViewProvider INSTANCE = new GlassFishWebModuleViewProvider(); private final static Logger LOGGER = Logger.getLogger(GlassFishWebModuleViewProvider.class.getName()); private final Map viewMap = new HashMap(); private static class GlassfishWebModuleView extends DataSourceView { //~ Static fields/initializers ------------------------------------------------------------------------------------------- private static final Image NODE_ICON = ImageUtilities.loadImage("net/java/visualvm/modules/glassfish/resources/application.png", true); //~ Instance fields ------------------------------------------------------------------------------------------------------ private SimpleXYChartSupport activeSessionsChart; private SimpleXYChartSupport jspChart; private SimpleXYChartSupport totalSessionsChart; private DataViewComponent dvc; private TableModel servletsModel; private TableModel wsModel; private GlassFishWebModule module; private ScheduledTask refreshTask; //~ Constructors --------------------------------------------------------------------------------------------------------- public GlassfishWebModuleView(GlassFishWebModule webModule) { super(webModule, "Overview", NODE_ICON, 0, true); module = webModule; JPanel masterPanel = new JPanel(new BorderLayout()); masterPanel.setOpaque(false); HTMLTextArea generalDataArea = new HTMLTextArea(); generalDataArea.setText(buildInfo()); generalDataArea.setBorder(BorderFactory.createEmptyBorder()); // generalDataArea.setOpaque(false); JScrollPane generalDataScroll = new JScrollPane(generalDataArea); generalDataScroll.setViewportBorder(BorderFactory.createEmptyBorder()); generalDataScroll.setBorder(BorderFactory.createEmptyBorder()); generalDataScroll.setOpaque(false); HTMLLabel appLink = new HTMLLabel("

Application hosted by " + DataSourceDescriptorFactory.getDescriptor(module.getGlassFishRoot().getApplication()).getName()+ "

") { protected void showURL(URL url) { DataSourceWindowManager.sharedInstance().openDataSource(module.getGlassFishRoot().getApplication()); } }; masterPanel.add(generalDataScroll, BorderLayout.CENTER); masterPanel.add(appLink, BorderLayout.NORTH); SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500); desc.addLineItems("Current","Maximum"); activeSessionsChart = ChartFactory.createSimpleXYChart(desc); desc = SimpleXYChartDescriptor.decimal(10, true, 500); desc.addLineItems("Created","Expired","Rejected"); totalSessionsChart = ChartFactory.createSimpleXYChart(desc); desc = SimpleXYChartDescriptor.decimal(10, false, 500); desc.addLineItems("Count","Reloads","Errors"); jspChart = ChartFactory.createSimpleXYChart(desc); JPanel servletsPanel = new JPanel(new BorderLayout()); servletsPanel.setOpaque(false); servletsModel = new ServletTableModel(webModule.getMonitor(), Quantum.seconds(5)); RowSorter servletsRowSorter = new TableRowSorter(servletsModel); StatsTable servletsTable = new StatsTable(servletsModel); servletsTable.setRowSorter(servletsRowSorter); JScrollPane servletsScroller = new JScrollPane(servletsTable); servletsScroller.getViewport().setBackground(generalDataArea.getBackground()); servletsPanel.add(servletsScroller, BorderLayout.CENTER); JPanel wsPanel = new JPanel(new BorderLayout()); wsPanel.setOpaque(false); wsModel = new WSTableModel(webModule.getMonitor(), Quantum.seconds(5)); RowSorter wsRowSorter = new TableRowSorter(wsModel); StatsTable wsTable = new StatsTable(wsModel); wsTable.setRowSorter(wsRowSorter); JScrollPane wsScroller = new JScrollPane(wsTable); wsScroller.getViewport().setBackground(generalDataArea.getBackground()); wsPanel.add(wsScroller, BorderLayout.CENTER); DataViewComponent.MasterView masterView = new DataViewComponent.MasterView("Overview", null, masterPanel); DataViewComponent.MasterViewConfiguration masterConfiguration = new DataViewComponent.MasterViewConfiguration(false); dvc = new DataViewComponent(masterView, masterConfiguration); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("Sessions", true), DataViewComponent.TOP_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("Sessions Active", null, 10, activeSessionsChart.getChart(), null), DataViewComponent.TOP_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("Sessions Total", null, 20, totalSessionsChart.getChart(), null), DataViewComponent.TOP_LEFT); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("JSPs", true), DataViewComponent.TOP_RIGHT); dvc.addDetailsView(new DataViewComponent.DetailsView("JSPs", null, 10, jspChart.getChart(), null), DataViewComponent.TOP_RIGHT); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("Runtime", true), DataViewComponent.BOTTOM_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("Servlets", null, 10, servletsPanel, null), DataViewComponent.BOTTOM_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("WebServices", null, 20, wsPanel, null), DataViewComponent.BOTTOM_LEFT); refreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() { public void onSchedule(long timeStamp) { try { refreshData(timeStamp); } catch (Exception e) { if (!(e instanceof UndeclaredThrowableException)) { Logger.getLogger(GlassFishWebModuleViewProvider.class.getName()).log(Level.INFO,"onSchedule",e); } else { Scheduler.sharedInstance().unschedule(refreshTask); refreshTask = null; } } } }, Quantum.seconds(5)); } @Override protected DataViewComponent createComponent() { return dvc; } //~ Methods -------------------------------------------------------------------------------------------------------------- private String buildInfo() { JmxModel jmx = JmxModelFactory.getJmxModelFor(module.getGlassFishRoot().getApplication()); StringBuilder sb = new StringBuilder(); try { ObjectName objName = new ObjectName(module.getObjectName()); MBeanServerConnection connection = jmx.getMBeanServerConnection(); sb.append("
"); sb.append("Context: ").append(connection.getAttribute(objName, "path")).append("
"); sb.append("Document Base: ").append(connection.getAttribute(objName, "docBase")).append("
"); sb.append("Working Dir: ").append(connection.getAttribute(objName, "workDir")).append("
"); sb.append("
"); boolean cacheAllowed = (Boolean)connection.getAttribute(objName, "cachingAllowed"); sb.append("Caching: ").append(cacheAllowed ? "Allowed" : "Disallowed").append("
"); sb.append("
"); } catch (MBeanException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (AttributeNotFoundException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (InstanceNotFoundException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (ReflectionException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (IOException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (MalformedObjectNameException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (NullPointerException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } return sb.toString(); } private void refreshData(long sampleTime) { WebModuleVirtualServerMonitor monitor = module.getMonitor(); WebModuleVirtualServerStats stats = monitor.getWebModuleVirtualServerStats(); activeSessionsChart.addValues(sampleTime, new long[] { stats.getActiveSessionsCurrent().getCount(), stats.getActiveSessionsHigh().getCount() }); totalSessionsChart.addValues(sampleTime, new long[] { stats.getSessionsTotal().getCount(), stats.getExpiredSessionsTotal().getCount(), stats.getRejectedSessionsTotal().getCount() }); jspChart.addValues(sampleTime, new long[] { stats.getJSPCount().getCount(), stats.getJSPReloadCount().getCount(), stats.getJSPErrorCount().getCount() }); } } private GlassFishWebModuleViewProvider() {} //~ Methods ------------------------------------------------------------------------------------------------------------------ public static void initialize() { DataSourceViewsManager.sharedInstance().addViewProvider(INSTANCE, GlassFishWebModule.class); } public static void shutdown() { DataSourceViewsManager.sharedInstance().removeViewProvider(INSTANCE); INSTANCE.viewMap.clear(); } @Override protected DataSourceView createView(GlassFishWebModule webModule) { return new GlassfishWebModuleView(webModule); } @Override protected boolean supportsViewFor(GlassFishWebModule webModule) { return true; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/HTTPServiceView.java ================================================ package net.java.visualvm.modules.glassfish.dataview; import com.sun.appserv.management.monitor.ConnectionQueueMonitor; import com.sun.appserv.management.monitor.FileCacheMonitor; import com.sun.appserv.management.monitor.HTTPServiceMonitor; import com.sun.appserv.management.monitor.KeepAliveMonitor; import com.sun.appserv.management.monitor.statistics.KeepAliveStats; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.charts.ChartFactory; import org.graalvm.visualvm.charts.SimpleXYChartDescriptor; import org.graalvm.visualvm.charts.SimpleXYChartSupport; import org.graalvm.visualvm.core.scheduler.Quantum; import org.graalvm.visualvm.core.scheduler.ScheduledTask; import org.graalvm.visualvm.core.scheduler.Scheduler; import org.graalvm.visualvm.core.scheduler.SchedulerTask; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.uisupport.HTMLTextArea; import java.lang.reflect.UndeclaredThrowableException; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; class HTTPServiceView extends DataSourceView { private static final String ICON_PATH = "net/java/visualvm/modules/glassfish/resources/logviewer_icon.png"; private static final Logger LOGGER = Logger.getLogger(HTTPServiceView.class.getName()); private DataViewComponent dvc; private HTTPServiceMonitor monitor; private ScheduledTask queueRefreshTask; private ScheduledTask cacheRefreshTask; private ScheduledTask kaRefreshTask; public HTTPServiceView(Application app, HTTPServiceMonitor monitor) { super(app, "HTTP Service", new ImageIcon(ImageUtilities.loadImage(ICON_PATH, true)).getImage(), POSITION_AT_THE_END, false); this.monitor = monitor; initComponents(); } @Override public DataViewComponent createComponent() { return dvc; } private SimpleXYChartSupport connectionQueueChart; private void configureConnectionQueueVisualizer() { final ConnectionQueueMonitor cqm = monitor.getConnectionQueueMonitor(); SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, true, 500); desc.addLineItems("1min","5min","15min"); connectionQueueChart = ChartFactory.createSimpleXYChart(desc); // ConnectionQueuePanel cqp = new ConnectionQueuePanel(); // final ConnectionQueuePanel.Model model = new ConnectionQueuePanel.Model() { // // ConnectionQueueMonitor queueMonitor = null; // { // if (monitor != null) { // queueMonitor = monitor.getConnectionQueueMonitor(); // } // } // // @Override // public RangedLong getUtilization() { // if (queueMonitor == null) { // return RangedLong.ZERO; // } // ConnectionQueueStats stats = queueMonitor.getConnectionQueueStats(); // long max = stats.getMaxQueued().getCount(); // long current = stats.getCountQueued().getCount(); // return new RangedLong(0L, max, current); // } // // @Override // public int getRefusalRate() { // if (queueMonitor == null) { // return 0; // } // ConnectionQueueStats stats = queueMonitor.getConnectionQueueStats(); // // if (stats.getCountTotalQueued().getCount() == 0) { // return 0; // } // // return Math.round(((float) stats.getCountOverflows().getCount() / (float) stats.getCountTotalConnections().getCount()) * 100.0F); // } // // @Override // public long getAverage1min() { // if (queueMonitor == null) { // return 0L; // } // ConnectionQueueStats stats = queueMonitor.getConnectionQueueStats(); // // return stats.getCountQueued1MinuteAverage().getCount(); // } // // @Override // public long getAverage5min() { // if (queueMonitor == null) { // return 0L; // } // ConnectionQueueStats stats = queueMonitor.getConnectionQueueStats(); // // return stats.getCountQueued5MinuteAverage().getCount(); // } // // @Override // public long getAverage15min() { // if (queueMonitor == null) { // return 0L; // } // ConnectionQueueStats stats = queueMonitor.getConnectionQueueStats(); // // return stats.getCountQueued15MinuteAverage().getCount(); // } // }; // cqp.setModel(model); queueRefreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() { @Override public void onSchedule(long timeStamp) { try { connectionQueueChart.addValues(timeStamp, new long[] {cqm.getConnectionQueueStats().getCountQueued1MinuteAverage().getCount(), cqm.getConnectionQueueStats().getCountQueued5MinuteAverage().getCount(), cqm.getConnectionQueueStats().getCountQueued15MinuteAverage().getCount()}); } catch (Exception e) { if (!(e instanceof UndeclaredThrowableException)) { LOGGER.log(Level.INFO,"onSchedule",e); } else { Scheduler.sharedInstance().unschedule(queueRefreshTask); queueRefreshTask = null; } } } }, Quantum.seconds(1)); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("Connection Queue", true), DataViewComponent.TOP_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("Connection Queue", null, 10, connectionQueueChart.getChart(), null), DataViewComponent.TOP_LEFT); } private SimpleXYChartSupport fileCacheChart; private void configureFileCacheVisualizer() { SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500); desc.addLineFillItems("Min"); desc.addLineItems("Max","Current"); fileCacheChart = ChartFactory.createSimpleXYChart(desc); final FileCacheMonitor fcm = monitor.getFileCacheMonitor(); // FileCachePanel fcp = new FileCachePanel(); // final FileCachePanel.Model model = new FileCachePanel.Model() { // // FileCacheMonitor cacheMonitor = null; // { // if (monitor != null) { // cacheMonitor = monitor.getFileCacheMonitor(); // } // } // // @Override // public RangedLong getUtilizationHeap() { // if (cacheMonitor == null) { // return RangedLong.ZERO; // } // FileCacheStats stats = cacheMonitor.getFileCacheStats(); // return new RangedLong(0L, stats.getMaxHeapCacheSize().getCount(), stats.getSizeHeapCache().getCount()); // } // // @Override // public RangedLong getUtilizationAll() { // if (cacheMonitor == null) { // return RangedLong.ZERO; // } // FileCacheStats stats = cacheMonitor.getFileCacheStats(); // return new RangedLong(0L, stats.getMaxEntries().getCount(), stats.getMaxEntries().getCount()); // } // // @Override // public RangedLong getUtilizationOpen() { // if (cacheMonitor == null) { // return RangedLong.ZERO; // } // FileCacheStats stats = cacheMonitor.getFileCacheStats(); // return new RangedLong(0L, stats.getMaxOpenEntries().getCount(), stats.getCountOpenEntries().getCount()); // } // // @Override // public RangedLong getHitRatio() { // if (cacheMonitor == null) { // return RangedLong.ZERO; // } // FileCacheStats stats = cacheMonitor.getFileCacheStats(); // // long hits = stats.getCountContentHits().getCount(); // long misses = stats.getCountContentMisses().getCount(); // return new RangedLong(0L, hits + misses, misses); // } // }; // // fcp.setModel(model); final long[] minmax = new long[]{Long.MAX_VALUE, 0L}; cacheRefreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() { @Override public void onSchedule(long timeStamp) { try { long hits = fcm.getFileCacheStats().getCountContentHits().getCount(); long misses = fcm.getFileCacheStats().getCountContentMisses().getCount(); long percent = (hits + misses > 0) ? (hits * 100) / (hits + misses) : 0L; if (percent > minmax[1]) { minmax[1] = percent; } if (percent < minmax[0]) { minmax[0] = percent; } fileCacheChart.addValues(timeStamp, new long[] { minmax[0], minmax[1], percent }); } catch (Exception e) { if (!(e instanceof UndeclaredThrowableException)) { LOGGER.log(Level.INFO,"onSchedule",e); } else { Scheduler.sharedInstance().unschedule(cacheRefreshTask); cacheRefreshTask = null; } } } }, Quantum.seconds(1)); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("File Cache", true), DataViewComponent.BOTTOM_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("File Cache Hits", null, 10, fileCacheChart.getChart(), null), DataViewComponent.BOTTOM_LEFT); } private void configureHttpServiceVisualizer() { configureConnectionQueueVisualizer(); configureFileCacheVisualizer(); configureKeepAliveVisualizer(); } private SimpleXYChartSupport keepAliveChart; private void configureKeepAliveVisualizer() { final KeepAliveMonitor kaMonitor = monitor.getKeepAliveMonitor(); SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500); desc.addLineItems("Refused","Flushed","Timed Out"); keepAliveChart = ChartFactory.createSimpleXYChart(desc); kaRefreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() { @Override public void onSchedule(long timeStamp) { try { KeepAliveStats stats = kaMonitor.getKeepAliveStats(); keepAliveChart.addValues(timeStamp, new long[] {stats.getCountRefusals().getCount(), stats.getCountFlushes().getCount(), stats.getCountTimeouts().getCount()}); } catch (Exception e) { if (!(e instanceof UndeclaredThrowableException)) { LOGGER.log(Level.INFO,"onSchedule",e); } else { Scheduler.sharedInstance().unschedule(kaRefreshTask); kaRefreshTask = null; } } } }, Quantum.seconds(1)); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("Keep Alive", true), DataViewComponent.BOTTOM_RIGHT); dvc.addDetailsView(new DataViewComponent.DetailsView("Keep Alive", null, 10, keepAliveChart.getChart(), null), DataViewComponent.BOTTOM_RIGHT); } private void initComponents() { HTMLTextArea generalDataArea = new HTMLTextArea(); generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8)); // DisplayArea monitoringDisplayArea = new DisplayArea(); // monitoringDisplayArea.setClosable(true); DataViewComponent.MasterView monitoringMasterView = new DataViewComponent.MasterView("", null, generalDataArea); DataViewComponent.MasterViewConfiguration monitoringMasterConfiguration = new DataViewComponent.MasterViewConfiguration(false); dvc = new DataViewComponent(monitoringMasterView, monitoringMasterConfiguration); configureHttpServiceVisualizer(); } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/ServletTableModel.java ================================================ package net.java.visualvm.modules.glassfish.dataview; import com.sun.appserv.management.monitor.ServletMonitor; import com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor; import com.sun.appserv.management.monitor.statistics.AltServletStats; import org.graalvm.visualvm.core.scheduler.Quantum; import java.util.Map; class ServletTableModel extends AbstractStatsTableModel { public ServletTableModel(WebModuleVirtualServerMonitor aMonitor, Quantum refreshInterval) { super(aMonitor, refreshInterval); } @Override protected Map getMonitorMap() { return monitor.getServletMonitorMap(); } @Override protected AltServletStats getStats(ServletMonitor monitor) { return monitor.getAltServletStats(); } @Override protected boolean isDisplayable(AltServletStats stats) { return true; // return stats.getRequestCount().getCount() > 0; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/TransactionServiceView.java ================================================ package net.java.visualvm.modules.glassfish.dataview; import com.sun.appserv.management.monitor.TransactionServiceMonitor; import com.sun.appserv.management.monitor.statistics.TransactionServiceStats; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.charts.ChartFactory; import org.graalvm.visualvm.charts.SimpleXYChartDescriptor; import org.graalvm.visualvm.charts.SimpleXYChartSupport; import org.graalvm.visualvm.core.scheduler.Quantum; import org.graalvm.visualvm.core.scheduler.ScheduledTask; import org.graalvm.visualvm.core.scheduler.Scheduler; import org.graalvm.visualvm.core.scheduler.SchedulerTask; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.uisupport.HTMLTextArea; import java.lang.reflect.UndeclaredThrowableException; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; class TransactionServiceView extends DataSourceView { private static final String ICON_PATH = "net/java/visualvm/modules/glassfish/resources/logviewer_icon.png"; private DataViewComponent dvc; private TransactionServiceMonitor monitor; private ScheduledTask transRefreshTask; public TransactionServiceView(Application app, TransactionServiceMonitor monitor) { super(app, "Transaction Service", new ImageIcon(ImageUtilities.loadImage(ICON_PATH, true)).getImage(), POSITION_AT_THE_END, false); this.monitor = monitor; initComponents(); } @Override public DataViewComponent createComponent() { return dvc; } private SimpleXYChartSupport transactionalServiceChart; private void configureTransactionalServiceVisualizer() { SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500); desc.addFillItems("Count","Maximum Time"); transactionalServiceChart = ChartFactory.createSimpleXYChart(desc); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("Transactional Service", false), DataViewComponent.BOTTOM_RIGHT); final TransactionServiceStats tss = monitor.getTransactionServiceStats(); transRefreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() { @Override public void onSchedule(long timeStamp) { try { transactionalServiceChart.addValues(timeStamp, new long[]{tss.getActiveCount().getCount()}); } catch (Exception e) { if (!(e instanceof UndeclaredThrowableException)) { Logger.getLogger(TransactionServiceView.class.getName()).log(Level.INFO,"onSchedule",e); } else { Scheduler.sharedInstance().unschedule(transRefreshTask); transRefreshTask = null; } } } }, Quantum.seconds(1)); dvc.addDetailsView(new DataViewComponent.DetailsView("Transactional Service", null, 10, transactionalServiceChart.getChart(), null), DataViewComponent.BOTTOM_RIGHT); } private void initComponents() { HTMLTextArea generalDataArea = new HTMLTextArea(); generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8)); DataViewComponent.MasterView monitoringMasterView = new DataViewComponent.MasterView("", null, generalDataArea); DataViewComponent.MasterViewConfiguration monitoringMasterConfiguration = new DataViewComponent.MasterViewConfiguration(true); dvc = new DataViewComponent(monitoringMasterView, monitoringMasterConfiguration); configureTransactionalServiceVisualizer(); } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/WSTableModel.java ================================================ package net.java.visualvm.modules.glassfish.dataview; import com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor; import com.sun.appserv.management.monitor.WebServiceEndpointMonitor; import com.sun.appserv.management.monitor.statistics.WebServiceEndpointAggregateStats; import org.graalvm.visualvm.core.scheduler.Quantum; import java.util.Map; class WSTableModel extends AbstractStatsTableModel { public WSTableModel(WebModuleVirtualServerMonitor aMonitor, Quantum refreshInterval) { super(aMonitor, refreshInterval); } @Override protected Map getMonitorMap() { return monitor.getWebServiceEndpointMonitorMap(); } @Override protected WebServiceEndpointAggregateStats getStats(WebServiceEndpointMonitor monitor) { return monitor.getWebServiceEndpointAggregateStats(); } @Override protected boolean isDisplayable(WebServiceEndpointAggregateStats stats) { return true; // return stats.getTotalFaults().getCount() + stats.getTotalNumSuccess().getCount() > 0; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/AMXUtil.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.jmx; import com.sun.appserv.management.DomainRoot; import com.sun.appserv.management.base.SystemInfo; import com.sun.appserv.management.client.ProxyFactory; import com.sun.appserv.management.config.ConfigConfig; import com.sun.appserv.management.config.ModuleMonitoringLevelsConfig; import com.sun.appserv.management.monitor.MonitoringRoot; import com.sun.appserv.management.util.jmx.MBeanServerConnectionConnectionSource; import org.graalvm.visualvm.tools.jmx.JmxModel; import java.lang.ref.WeakReference; import java.util.Map; import java.util.WeakHashMap; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.MBeanServerConnection; /** * * @author Jaroslav Bachorik */ public class AMXUtil { private static final Logger LOGGER = Logger.getLogger(AMXUtil.class.getName()); private static final Map> proxyMap = new WeakHashMap>(); public static MonitoringRoot getMonitoringRoot(MBeanServerConnection connection) throws Exception { DomainRoot dr = getDomainRoot(connection); if (dr == null) return null; return dr.getMonitoringRoot(); } public static DomainRoot getDomainRoot(JmxModel model) { try { return getDomainRoot(model.getMBeanServerConnection()); } catch (Exception e) { return null; } } public static DomainRoot getDomainRoot(MBeanServerConnection connection) throws Exception { try { DomainRoot domainRoot = getAMXProxyFactory(connection).getDomainRoot(); domainRoot.waitAMXReady(); return domainRoot; } catch (Exception e) { LOGGER.log(Level.FINER, "", e); return null; } } public static ModuleMonitoringLevelsConfig getMonitoringConfig(JmxModel jmxModel) { ConfigConfig cc = getDomainRoot(jmxModel).getDomainConfig().getConfigConfigMap().get(JMXUtil.getServerConfig(jmxModel)); return cc.getMonitoringServiceConfig().getModuleMonitoringLevelsConfig(); } public static ProxyFactory getAMXProxyFactory(MBeanServerConnection connection) throws Exception { WeakReference pfref = proxyMap.get(connection); ProxyFactory pf = null; if (pfref != null && pfref.get() != null && pfref.get().getDomainRoot() != null) { pf = pfref.get(); try { pf.getDomainRoot().getAMXReady(); return pf; } catch (Exception e) {} } pf = ProxyFactory.getInstance(new MBeanServerConnectionConnectionSource(connection), false); proxyMap.put(connection, new WeakReference(pf)); return pf; } public static boolean isEE(DomainRoot dr) { SystemInfo systemInfo = dr.getSystemInfo(); return systemInfo.supportsFeature(SystemInfo.CLUSTERS_FEATURE); } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/Bundle.properties ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ JMXDetailsPanel.jLabel1.text=User Name: JMXDetailsPanel.jLabel2.text=Password: JMXDetailsPanel.jLabel3.text=MBean Server Port: JMXDetailsPanel.jTextField1.text=jTextField1 JMXDetailsPanel.jTextField2.text=jTextField2 JMXDetailsPanel.jLabel1.text_1=User Name: JMXDetailsPanel.jLabel2.text_1=Password: JMXDetailsPanel.jLabel3.text_1=MBean Server Port: JMXDetailsPanel.userName.text_1=admin JMXDetailsPanel.password.text=adminadmin ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/GFJmxModelFactory.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.jmx; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.type.ApplicationType; import org.graalvm.visualvm.application.type.ApplicationTypeFactory; import org.graalvm.visualvm.core.datasource.Storage; import org.graalvm.visualvm.core.model.ModelFactory; import org.graalvm.visualvm.core.model.ModelProvider; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.net.MalformedURLException; import javax.management.remote.JMXServiceURL; import net.java.visualvm.modules.glassfish.GlassFishApplicationType; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; /** * * @author Jaroslav Bachorik */ public class GFJmxModelFactory extends ModelFactory implements ModelProvider{ private static final String STORAGE_DIRNAME = "jmxapplicationsGF"; // copy from JmxApplicationsSupport .... private static final String PROPERTY_USERNAME = "prop_username"; // copy from JmxApplicationsSupport .... private static final String PROPERTY_PASSWORD = "prop_password"; // copy from JmxApplicationsSupport .... private static final Storage STORAGE = new Storage(new File(Storage.getPersistentStorageDirectoryString() + File.separator + STORAGE_DIRNAME)); private final static GFJmxModelFactory INSTANCE = new GFJmxModelFactory(); private DialogDescriptor credentialsDD = null; private JMXDetailsPanel credentialsPanel = null; public JmxModel createModelFor(Application app) { // Local applications will use the default JmxModelFactory if (app.isLocalApplication()) { return null; } // Non-GlassFish remote applications will use the default JmxModelFactory too ApplicationType at = ApplicationTypeFactory.getApplicationTypeFor(app); if (!(at instanceof GlassFishApplicationType)) { return null; } String userName = STORAGE.getCustomProperty(PROPERTY_USERNAME); String password = STORAGE.getCustomProperty(PROPERTY_PASSWORD); int serverPort = 8686; getCredentialsPanel().setPassword(password); getCredentialsPanel().setUserName(userName); if (DialogDisplayer.getDefault().notify(getDialogDescriptor()) == DialogDescriptor.OK_OPTION) { STORAGE.setCustomProperty(PROPERTY_USERNAME, getCredentialsPanel().getUserName()); STORAGE.setCustomProperty(PROPERTY_PASSWORD, getCredentialsPanel().getPassword()); serverPort = getCredentialsPanel().getServerPort(); } else { // Revert to default JmxModelFactory on Cancel button return null; } JMXServiceURL serverURL; try { serverURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + app.getHost().getHostName() + ":" + serverPort + "/jmxrmi"); } catch (MalformedURLException e) { return null; } return null; // return new JmxModel(new JmxApplication(app.getHost(), serverURL, STORAGE)); } @Override public int priority() { return 10; } public static void initialize() { JmxModelFactory.getDefault().registerProvider(INSTANCE); } public static void shutdown() { JmxModelFactory.getDefault().unregisterProvider(INSTANCE); } private synchronized DialogDescriptor getDialogDescriptor() { if (credentialsDD == null) { credentialsDD = new DialogDescriptor(getCredentialsPanel(), "JMX Credentials", true, DialogDescriptor.OK_CANCEL_OPTION, DialogDescriptor.CANCEL_OPTION, null); } return credentialsDD; } private synchronized JMXDetailsPanel getCredentialsPanel() { if (credentialsPanel == null) { credentialsPanel = new JMXDetailsPanel(); credentialsPanel.addPropertyChangeListener(JMXDetailsPanel.VALIDITY_PROPERTY, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { getDialogDescriptor().setValid(getCredentialsPanel().hasValidCredentials()); } }); } return credentialsPanel; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/JMXDetailsPanel.form ================================================
================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/JMXDetailsPanel.java ================================================ /* * JMXDetailsPanel.java * * Created on March 14, 2008, 9:17 AM */ package net.java.visualvm.modules.glassfish.jmx; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.Document; /** * * @author Jaroslav Bachorik */ public class JMXDetailsPanel extends javax.swing.JPanel { public static final String VALIDITY_PROPERTY = JMXDetailsPanel.class.getName() + "#isValid"; private boolean portValid = true; private boolean usernameValid = false; private boolean passwordValid = false; /** Creates new form JMXDetailsPanel */ public JMXDetailsPanel() { initComponents(); postInit(); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { jLabel1 = new javax.swing.JLabel(); userName = new javax.swing.JTextField(); jLabel2 = new javax.swing.JLabel(); password = new javax.swing.JPasswordField(); jLabel3 = new javax.swing.JLabel(); serverPort = new javax.swing.JSpinner(); jSeparator1 = new javax.swing.JSeparator(); jLabel1.setLabelFor(userName); jLabel1.setText(org.openide.util.NbBundle.getMessage(JMXDetailsPanel.class, "JMXDetailsPanel.jLabel1.text_1")); // NOI18N userName.setText(org.openide.util.NbBundle.getMessage(JMXDetailsPanel.class, "JMXDetailsPanel.userName.text_1")); // NOI18N jLabel2.setLabelFor(password); jLabel2.setText(org.openide.util.NbBundle.getMessage(JMXDetailsPanel.class, "JMXDetailsPanel.jLabel2.text_1")); // NOI18N password.setText(org.openide.util.NbBundle.getMessage(JMXDetailsPanel.class, "JMXDetailsPanel.password.text")); // NOI18N jLabel3.setText(org.openide.util.NbBundle.getMessage(JMXDetailsPanel.class, "JMXDetailsPanel.jLabel3.text_1")); // NOI18N serverPort.setModel(new javax.swing.SpinnerNumberModel(8686, 1024, 65535, 1)); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 253, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel1) .addComponent(jLabel2)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(password, javax.swing.GroupLayout.DEFAULT_SIZE, 164, Short.MAX_VALUE) .addComponent(userName, javax.swing.GroupLayout.DEFAULT_SIZE, 164, Short.MAX_VALUE))) .addGroup(layout.createSequentialGroup() .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(serverPort, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(userName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(password, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(16, 16, 16) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel3) .addComponent(serverPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JSeparator jSeparator1; private javax.swing.JPasswordField password; private javax.swing.JSpinner serverPort; private javax.swing.JTextField userName; // End of variables declaration//GEN-END:variables private void postInit() { serverPort.getModel().addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if (serverPort.getModel().getValue() != null && serverPort.getModel().getValue().toString().length() > 0) { portValid = true; } else { portValid = false; } firePropertyChange(VALIDITY_PROPERTY, null, null); } }); userName.getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { checkValidity(e.getDocument()); } public void removeUpdate(DocumentEvent e) { checkValidity(e.getDocument()); } public void changedUpdate(DocumentEvent e) { checkValidity(e.getDocument()); } private void checkValidity(Document document) { if (document.getLength() > 0) { usernameValid = true; } else { usernameValid = false; } firePropertyChange(VALIDITY_PROPERTY, null, null); } }); password.getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { checkValidity(e.getDocument()); } public void removeUpdate(DocumentEvent e) { checkValidity(e.getDocument()); } public void changedUpdate(DocumentEvent e) { checkValidity(e.getDocument()); } private void checkValidity(Document document) { if (document.getLength() > 0) { passwordValid = true; } else { passwordValid = false; } firePropertyChange(VALIDITY_PROPERTY, null, null); } }); } public int getServerPort() { return (Integer)serverPort.getModel().getValue(); } public void setServerPort(int value) { this.serverPort.getModel().setValue(value); } public String getUserName() { return userName.getText(); } public void setUserName(String value) { userName.setText(value); } public String getPassword() { return new String(password.getPassword()); } public void setPassword(String value) { password.setText(value); } public boolean hasValidCredentials() { return portValid && usernameValid && passwordValid; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/JMXUtil.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.jmx; import org.graalvm.visualvm.tools.jmx.JmxModel; import java.io.IOException; import java.util.Map; import java.util.logging.Logger; import javax.management.AttributeNotFoundException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.ReflectionException; import org.openide.util.Exceptions; /** * * @author Jaroslav Bachorik */ public class JMXUtil { private static final Logger LOGGER = Logger.getLogger(JMXUtil.class.getName()); public static final String getServerName(JmxModel jmx) { try { Object serverNameObj = jmx.getMBeanServerConnection().getAttribute(new ObjectName("com.sun.appserv:j2eeType=J2EEServer,name=server,category=runtime"), "J2EEServer"); return serverNameObj != null ? serverNameObj.toString() : null; } catch (MalformedObjectNameException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerName", ex); } catch (NullPointerException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerName", ex); } catch (MBeanException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerName", ex); } catch (AttributeNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerName", ex); } catch (InstanceNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerName", ex); } catch (ReflectionException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerName", ex); } catch (IOException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerName", ex); } return null; } public static final String getServerConfig(JmxModel jmx) { try { Object serverConfObj = jmx.getMBeanServerConnection().getAttribute(new ObjectName("com.sun.appserv:j2eeType=J2EEServer,name=server,category=runtime"), "config-ref"); return serverConfObj != null ? serverConfObj.toString() : null; } catch (MalformedObjectNameException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfig", ex); } catch (NullPointerException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfig", ex); } catch (MBeanException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfig", ex); } catch (AttributeNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfig", ex); } catch (InstanceNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfig", ex); } catch (ReflectionException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfig", ex); } catch (IOException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfig", ex); } return null; } public static final String getServerConfigDir(JmxModel jmx) { try { Object serverConfDirObj = jmx.getMBeanServerConnection().invoke(new ObjectName("com.sun.appserv:type=domain,category=config"), "getConfigDir", null, null); return serverConfDirObj != null ? serverConfDirObj.toString() : null; } catch (MalformedObjectNameException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfigDir", ex); } catch (NullPointerException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfigDir", ex); } catch (MBeanException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfigDir", ex); } catch (InstanceNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfigDir", ex); } catch (ReflectionException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfigDir", ex); } catch (IOException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerConfigDir", ex); } return null; } public static final String getServerDomain(JmxModel jmx) { try { Object serverDomainObj = jmx.getMBeanServerConnection().invoke(new ObjectName("com.sun.appserv:type=domain,category=config"), "getName", null, null); return serverDomainObj != null ? serverDomainObj.toString() : null; } catch (MalformedObjectNameException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerDomain", ex); } catch (NullPointerException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerDomain", ex); } catch (MBeanException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerDomain", ex); } catch (InstanceNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerDomain", ex); } catch (ReflectionException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerDomain", ex); } catch (IOException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getServerDomain", ex); } return null; } public static final String getObjectName(String type, String moduleUniqueName, JmxModel jmx) { try { for(String deplObjName : getDeployedObjects(jmx)) { if (deplObjName.startsWith("com.sun.appserv:j2eeType=" + type + ",name=" + moduleUniqueName)) { return deplObjName; } } } catch (NullPointerException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getObjectName", ex); } return moduleUniqueName; } public static final String getJ2EEAppName(String objectName) { int startIndex = objectName.indexOf(",J2EEApplication="); int stopIndex = -1; if (startIndex > -1) { stopIndex = objectName.indexOf(",", startIndex + 1); } if (startIndex > -1 && stopIndex > -1 && stopIndex > startIndex) { String appName = objectName.substring(startIndex + 17, stopIndex - 1); if (appName == null || appName.startsWith("nul")) return null; return new String(appName); } else { return null; } } public static final String getWebModuleName(String objectName, JmxModel jmx) { try { return (String) jmx.getMBeanServerConnection().getAttribute(new ObjectName(objectName), "name"); } catch (MBeanException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (AttributeNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (InstanceNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (ReflectionException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (IOException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (MalformedObjectNameException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (NullPointerException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } return null; } public static final String getWebModuleName(String objectName, JmxModel jmx, Map context2name) { try { String ctxMapping = (String) jmx.getMBeanServerConnection().getAttribute(new ObjectName(objectName), "name"); if (!ctxMapping.startsWith("/")) ctxMapping = "/" + ctxMapping; return context2name.get(ctxMapping); } catch (MBeanException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (AttributeNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (InstanceNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (ReflectionException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (IOException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (MalformedObjectNameException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } catch (NullPointerException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getWebModuleName", ex); } return null; } public static final String[] getDeployedObjects(JmxModel jmx) { try { ObjectName on = new ObjectName("com.sun.appserv:j2eeType=J2EEServer,name=server,category=runtime"); return (String[]) jmx.getMBeanServerConnection().getAttribute(on, "deployedObjects"); } catch (MBeanException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getDeployedObjects", ex); } catch (AttributeNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getDeployedObjects", ex); } catch (InstanceNotFoundException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getDeployedObjects", ex); } catch (ReflectionException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getDeployedObjects", ex); } catch (IOException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getDeployedObjects", ex); } catch (MalformedObjectNameException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getDeployedObjects", ex); } catch (NullPointerException ex) { LOGGER.throwing(JMXUtil.class.getName(), "getDeployedObjects", ex); } return new String[0]; } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/ui/Bundle.properties ================================================ Tester.jToggleButton1.text=M ConnectionQueuePanel.labelUtilization.text=Connections: ConnectionQueuePanel.lableRefusalRate.text=Refusal Rate [%]: HttpListenerPanel.labelThreads.text=Threads: HttpListenerPanel.labelListeners.text=Listener: FileCachePanel.labelHitRatio.text=Hit Ratio: KeepAlivePanel.labelUtilization.text=Utilization: TransactionsPanel.labelCommits.text=Commits [%]: TransactionsPanel.labelRollbacks.text=Rollbacks [%]: FileCachePanel.jLabel1.text=Cache Utilization [%] ConnectionQueuePanel.jLabel1.text=Averages KeepAlivePanel.jLabel1.text=Finished Connections TransactionsPanel.jLabel1.text=Active Transactions ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/ui/GenericModel.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.ui; import java.util.Observable; /** * * @author Jaroslav Bachorik */ public class GenericModel extends Observable { private long lastTimeStamp; //~ Inner Classes ------------------------------------------------------------------------------------------------------------ public static class RangedLong { //~ Instance fields ------------------------------------------------------------------------------------------------------ public final long max; public final long min; public final long val; //~ Constructors --------------------------------------------------------------------------------------------------------- public RangedLong(long min, long max, long val) { this.min = min; this.max = max; this.val = val; } public static final RangedLong ZERO = new RangedLong(0, 0, 0); } public long getLastTimeStamp() { return lastTimeStamp; } public void refresh(long timeStamp) { lastTimeStamp = timeStamp; setChanged(); } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/ui/StatsTable.java ================================================ package net.java.visualvm.modules.glassfish.ui; import java.util.Vector; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.event.TableModelEvent; import javax.swing.table.TableColumnModel; import javax.swing.table.TableModel; public class StatsTable extends JTable { private String selectedRowRef = null; { getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } public StatsTable(Object[][] rowData, Object[] columnNames) { super(rowData, columnNames); } public StatsTable(Vector rowData, Vector columnNames) { super(rowData, columnNames); } public StatsTable(int numRows, int numColumns) { super(numRows, numColumns); } public StatsTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) { super(dm, cm, sm); } public StatsTable(TableModel dm, TableColumnModel cm) { super(dm, cm); } public StatsTable(TableModel dm) { super(dm); } public StatsTable() { super(); } @Override public void tableChanged(TableModelEvent e) { selectedRowRef = getSelectedRowID(); super.tableChanged(e); setSelectedRowByID(selectedRowRef); } private String getSelectedRowID() { int rc = getRowCount(); int sr = getSelectedRow(); if (getRowCount() == 0 || getSelectedRow() <= 0) { return null; } return getValueAt(getSelectedRow(), 0).toString(); } private void setSelectedRowByID(String id) { if (id == null) { return; } for (int i = 0; i < getRowCount(); i++) { if (getValueAt(i, 0).equals(id)) { setRowSelectionInterval(i, i); return; } } } } ================================================ FILE: plugins/glassfish/src/net/java/visualvm/modules/glassfish/ui/Tachometer.java ================================================ /* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.ui; import java.awt.AWTException; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.ImageCapabilities; import java.awt.Insets; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.font.GlyphVector; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.image.VolatileImage; import javax.swing.JComponent; import javax.swing.border.Border; /** * * @author Jaroslav Bachorik */ public class Tachometer extends JComponent { private int val = 0; private int max = 100; private int min = 0; private final static Dimension MINIMUM_SIZE = new Dimension(80, 80); private final static double MAX_ANGLE = 270d; @Override public void paint(Graphics g) { try { Border border = getBorder(); Insets insets = new Insets(0, 0, 0, 0); if (border != null) { insets = border.getBorderInsets(this); } int diameter = Math.min(getBounds().width - (insets.left + insets.right), getBounds().height - (insets.top + insets.bottom)) - 4; VolatileImage img = createVolatileImage(getBounds().width - (insets.left + insets.right), getBounds().height - (insets.top + insets.bottom), new ImageCapabilities(true)); Graphics2D gr = img.createGraphics(); gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); gr.drawOval(insets.left, insets.top, diameter, diameter); TextLayout textTl = new TextLayout("fERRARI", getFont(), gr.getFontRenderContext()); AffineTransform at = new AffineTransform(); at.translate(0, (float)getBounds().getHeight() - (insets.top + insets.bottom) - (float)textTl.getBounds().getHeight()); at.scale(2d, 2d); // at.shear(1.3d, 0.8d); Shape textShape = textTl.getOutline(at); gr.fill(textShape); // GlyphVector gv = getFont().createGlyphVector(gr.getFontRenderContext(), "fERRARI"); // Rectangle bounds = gv.getPixelBounds(gr.getFontRenderContext(), 0, 0); // double scale = (double)(getBounds().width - (insets.left + insets.right)) / (double)bounds.width; // for(int i=0;i { final private X x; final private Y y; public Touple(X aX, Y aY) { x = aX; y = aY; } public X getX() { return x; } public Y getY() { return y; } } ================================================ FILE: plugins/graaljs/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.graaljs. Downloading external binaries (external/ directory)... ================================================ FILE: plugins/graaljs/external/asm-util-9.2-license.txt ================================================ https://gitlab.ow2.org/asm/asm/blob/master/LICENSE.txt ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, France Telecom All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: plugins/graaljs/external/binaries-list ================================================ 6267785D7EA4BCC1A0D3F40DE7D05B77A6C2BEEC org.graalvm.js:js-scriptengine:22.3.0 42A5D241E5B92589DBF1CBB5DD3EAE0360707C8F org.graalvm.js:js:22.3.0 3D88E01158436B353C4B54A396D209F9E2791CEF org.graalvm.regex:regex:22.3.0 2E02DD479A207794D1A5A14B5A83D5556880C876 org.graalvm.truffle:truffle-api:22.3.0 83179E3310A2ECE87266923FEDE5EF7355C68C9A org.graalvm.sdk:graal-sdk:22.3.0 9E7D3304C23F9BA5CB71915F7CCE23231A57A445 com.ibm.icu:icu4j:71.1 FBC178FC5BA3DAB50FD7E8A5317B8B647C8E8946 org.ow2.asm:asm-util:9.2 ================================================ FILE: plugins/graaljs/external/icu4j-71.1-license.txt ================================================ UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE See Terms of Use for definitions of Unicode Inc.s Data Files and Software. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. COPYRIGHT AND PERMISSION NOTICE Copyright 1991-2022 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. ---------------------------------------------------------------------- Third-Party Software Licenses This section contains third-party software notices and/or additional terms for licensed third-party software components included within ICU libraries. ---------------------------------------------------------------------- ICU License - ICU 1.8.1 to ICU 57.1 COPYRIGHT AND PERMISSION NOTICE Copyright (c) 1995-2016 International Business Machines Corporation and others All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, provided that the above copyright notice(s) and this permission notice appear in all copies of the Software and that both the above copyright notice(s) and this permission notice appear in supporting documentation. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. All trademarks and registered trademarks mentioned herein are the property of their respective owners. ---------------------------------------------------------------------- Chinese/Japanese Word Break Dictionary Data (cjdict.txt) # The Google Chrome software developed by Google is licensed under # the BSD license. Other software included in this distribution is # provided under other licenses, as set forth below. # # The BSD License # http://opensource.org/licenses/bsd-license.php # Copyright (C) 2006-2008, Google Inc. # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided with # the distribution. # Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # The word list in cjdict.txt are generated by combining three word lists # listed below with further processing for compound word breaking. The # frequency is generated with an iterative training against Google web # corpora. # # * Libtabe (Chinese) # - https://sourceforge.net/project/?group_id=1519 # - Its license terms and conditions are shown below. # # * IPADIC (Japanese) # - http://chasen.aist-nara.ac.jp/chasen/distribution.html # - Its license terms and conditions are shown below. # # ---------COPYING.libtabe ---- BEGIN-------------------- # # /* # * Copyright (c) 1999 TaBE Project. # * Copyright (c) 1999 Pai-Hsiang Hsiao. # * All rights reserved. # * # * Redistribution and use in source and binary forms, with or without # * modification, are permitted provided that the following conditions # * are met: # * # * . Redistributions of source code must retain the above copyright # * notice, this list of conditions and the following disclaimer. # * . Redistributions in binary form must reproduce the above copyright # * notice, this list of conditions and the following disclaimer in # * the documentation and/or other materials provided with the # * distribution. # * . Neither the name of the TaBE Project nor the names of its # * contributors may be used to endorse or promote products derived # * from this software without specific prior written permission. # * # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # * OF THE POSSIBILITY OF SUCH DAMAGE. # */ # # /* # * Copyright (c) 1999 Computer Systems and Communication Lab, # * Institute of Information Science, Academia # * Sinica. All rights reserved. # * # * Redistribution and use in source and binary forms, with or without # * modification, are permitted provided that the following conditions # * are met: # * # * . Redistributions of source code must retain the above copyright # * notice, this list of conditions and the following disclaimer. # * . Redistributions in binary form must reproduce the above copyright # * notice, this list of conditions and the following disclaimer in # * the documentation and/or other materials provided with the # * distribution. # * . Neither the name of the Computer Systems and Communication Lab # * nor the names of its contributors may be used to endorse or # * promote products derived from this software without specific # * prior written permission. # * # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # * OF THE POSSIBILITY OF SUCH DAMAGE. # */ # # Copyright 1996 Chih-Hao Tsai @ Beckman Institute, # University of Illinois # c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4 # # ---------------COPYING.libtabe-----END-------------------------------- # # # ---------------COPYING.ipadic-----BEGIN------------------------------- # # Copyright 2000, 2001, 2002, 2003 Nara Institute of Science # and Technology. All Rights Reserved. # # Use, reproduction, and distribution of this software is permitted. # Any copy of this software, whether in its original form or modified, # must include both the above copyright notice and the following # paragraphs. # # Nara Institute of Science and Technology (NAIST), # the copyright holders, disclaims all warranties with regard to this # software, including all implied warranties of merchantability and # fitness, in no event shall NAIST be liable for # any special, indirect or consequential damages or any damages # whatsoever resulting from loss of use, data or profits, whether in an # action of contract, negligence or other tortuous action, arising out # of or in connection with the use or performance of this software. # # A large portion of the dictionary entries # originate from ICOT Free Software. The following conditions for ICOT # Free Software applies to the current dictionary as well. # # Each User may also freely distribute the Program, whether in its # original form or modified, to any third party or parties, PROVIDED # that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear # on, or be attached to, the Program, which is distributed substantially # in the same form as set out herein and that such intended # distribution, if actually made, will neither violate or otherwise # contravene any of the laws and regulations of the countries having # jurisdiction over the User or the intended distribution itself. # # NO WARRANTY # # The program was produced on an experimental basis in the course of the # research and development conducted during the project and is provided # to users as so produced on an experimental basis. Accordingly, the # program is provided without any warranty whatsoever, whether express, # implied, statutory or otherwise. The term "warranty" used herein # includes, but is not limited to, any warranty of the quality, # performance, merchantability and fitness for a particular purpose of # the program and the nonexistence of any infringement or violation of # any right of any third party. # # Each user of the program will agree and understand, and be deemed to # have agreed and understood, that there is no warranty whatsoever for # the program and, accordingly, the entire risk arising from or # otherwise connected with the program is assumed by the user. # # Therefore, neither ICOT, the copyright holder, or any other # organization that participated in or was otherwise related to the # development of the program and their respective officials, directors, # officers and other employees shall be held liable for any and all # damages, including, without limitation, general, special, incidental # and consequential damages, arising out of or otherwise in connection # with the use or inability to use the program or any product, material # or result produced or otherwise obtained by using the program, # regardless of whether they have been advised of, or otherwise had # knowledge of, the possibility of such damages at any time during the # project or thereafter. Each user will be deemed to have agreed to the # foregoing by his or her commencement of use of the program. The term # "use" as used herein includes, but is not limited to, the use, # modification, copying and distribution of the program and the # production of secondary products from the program. # # In the case where the program, whether in its original form or # modified, was distributed or delivered to or received by a user from # any person, organization or entity other than ICOT, unless it makes or # grants independently of ICOT any specific warranty to the user in # writing, such person, organization or entity, will also be exempted # from and not be held liable to the user for any such damages as noted # above as far as the program is concerned. # # ---------------COPYING.ipadic-----END---------------------------------- ---------------------------------------------------------------------- Lao Word Break Dictionary Data (laodict.txt) # Copyright (C) 2016 and later: Unicode, Inc. and others. # License & terms of use: http://www.unicode.org/copyright.html # Copyright (c) 2015 International Business Machines Corporation # and others. All Rights Reserved. # # Project: https://github.com/rober42539/lao-dictionary # Dictionary: https://github.com/rober42539/lao-dictionary/laodict.txt # License: https://github.com/rober42539/lao-dictionary/LICENSE.txt # (copied below) # # This file is derived from the above dictionary version of Nov 22, 2020 # ---------------------------------------------------------------------- # Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. Redistributions in binary # form must reproduce the above copyright notice, this list of conditions and # the following disclaimer in the documentation and/or other materials # provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. # -------------------------------------------------------------------------- ---------------------------------------------------------------------- Burmese Word Break Dictionary Data (burmesedict.txt) # Copyright (c) 2014 International Business Machines Corporation # and others. All Rights Reserved. # # This list is part of a project hosted at: # github.com/kanyawtech/myanmar-karen-word-lists # # -------------------------------------------------------------------------- # Copyright (c) 2013, LeRoy Benjamin Sharon # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: Redistributions of source code must retain the above # copyright notice, this list of conditions and the following # disclaimer. Redistributions in binary form must reproduce the # above copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # Neither the name Myanmar Karen Word Lists, nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -------------------------------------------------------------------------- ---------------------------------------------------------------------- Time Zone Database ICU uses the public domain data and code derived from Time Zone Database for its time zone support. The ownership of the TZ database is explained in BCP 175: Procedure for Maintaining the Time Zone Database section 7. # 7. Database Ownership # # The TZ database itself is not an IETF Contribution or an IETF # document. Rather it is a pre-existing and regularly updated work # that is in the public domain, and is intended to remain in the # public domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do # not apply to the TZ Database or contributions that individuals make # to it. Should any claims be made and substantiated against the TZ # Database, the organization that is providing the IANA # Considerations defined in this RFC, under the memorandum of # understanding with the IETF, currently ICANN, may act in accordance # with all competent court orders. No ownership claims will be made # by ICANN or the IETF Trust on the database or the code. Any person # making a contribution to the database or code waives all rights to # future claims in that contribution or in the TZ Database. ---------------------------------------------------------------------- Google double-conversion Copyright 2006-2011, the V8 project authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- File: aclocal.m4 (only for ICU4C) Section: pkg.m4 - Macros to locate and utilise pkg-config. Copyright 2004 Scott James Remnant . Copyright 2012-2015 Dan Nicholson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception to the GNU General Public License, if you distribute this file as part of a program that contains a configuration script generated by Autoconf, you may include it under the same distribution terms that you use for the rest of that program. (The condition for the exception is fulfilled because ICU4C includes a configuration script generated by Autoconf, namely the `configure` script.) ---------------------------------------------------------------------- File: config.guess (only for ICU4C) This file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . As a special exception to the GNU General Public License, if you distribute this file as part of a program that contains a configuration script generated by Autoconf, you may include it under the same distribution terms that you use for the rest of that program. This Exception is an additional permission under section 7 of the GNU General Public License, version 3 ("GPLv3"). (The condition for the exception is fulfilled because ICU4C includes a configuration script generated by Autoconf, namely the `configure` script.) ---------------------------------------------------------------------- File: install-sh (only for ICU4C) Copyright 1991 by the Massachusetts Institute of Technology Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ================================================ FILE: plugins/graaljs/external/js-22.3.0-license.txt ================================================ Name: GraalJS Description: A high performance implementation of the JavaScript programming language. Built on the GraalVM by Oracle Labs. License: UPL Origin: https://github.com/oracle/graal Version: 22.3.0 Files: js-22.3.0.jar, js-scriptengine-22.3.0.jar, regex-22.3.0.jar, truffle-api-22.3.0.jar, graal-sdk-22.3.0.jar, Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. The Universal Permissive License (UPL), Version 1.0 Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this software, associated documentation and/or data (collectively the "Software"), free of charge and under any and all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or (ii) the Larger Works (as defined below), to deal in both (a) the Software, and (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software each a "Larger Work" to which the Software is contributed by such licensors), without restriction, including without limitation the rights to copy, create derivative works of, display, perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms. This license is subject to the following condition: The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: plugins/graaljs/manifest.mf ================================================ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: true OpenIDE-Module-Java-Dependencies: Java > 15 OpenIDE-Module: org.graalvm.visualvm.modules.graaljs OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/graaljs/Bundle.properties OpenIDE-Module-Specification-Version: 1.3 ================================================ FILE: plugins/graaljs/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/graaljs/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=520d0fe2 build.xml.script.CRC32=f245468f build.xml.stylesheet.CRC32=a56c6a5b@2.73 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=78de761a nbproject/build-impl.xml.script.CRC32=e26352d3 nbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73 ================================================ FILE: plugins/graaljs/nbproject/project.properties ================================================ file.reference.js-scriptengine-22.3.0.jar=external/js-scriptengine-22.3.0.jar file.reference.js-22.3.0.jar=external/js-22.3.0.jar file.reference.regex-22.3.0.jar=external/regex-22.3.0.jar file.reference.truffle-api-22.3.0.jar=external/truffle-api-22.3.0.jar file.reference.graal-sdk-22.3.0.jar=external/graal-sdk-22.3.0.jar file.reference.icu4j-71.1.jar=external/icu4j-71.1.jar file.reference.asm-util-9.2.jar=external/asm-util-9.2.jar is.eager=true license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Tomas Hurka nbm.needs.restart=true release.external/js-scriptengine-22.3.0.jar=modules/ext/js-scriptengine-22.3.0.jar release.external/js-22.3.0.jar=modules/ext/js-22.3.0.jar release.external/regex-22.3.0.jar=modules/ext/regex-22.3.0.jar release.external/truffle-api-22.3.0.jar=modules/ext/truffle-api-22.3.0.jar release.external/graal-sdk-22.3.0.jar=modules/ext/graal-sdk-22.3.0.jar release.external/icu4j-71.1.jar=modules/ext/icu4j-71.1.jar release.external/asm-util-9.2.jar=modules/ext/asm-util-9.2.jar javac.source=1.8 javac.compilerargs=-Xlint -Xlint:-serial ================================================ FILE: plugins/graaljs/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.graaljs org.netbeans.libs.asm 5.10 ext/js-scriptengine-22.3.0.jar external/js-scriptengine-22.3.0.jar ext/js-22.3.0.jar external/js-22.3.0.jar ext/regex-22.3.0.jar external/regex-22.3.0.jar ext/truffle-api-22.3.0.jar external/truffle-api-22.3.0.jar ext/graal-sdk-22.3.0.jar external/graal-sdk-22.3.0.jar ext/icu4j-71.1.jar external/icu4j-71.1.jar ext/asm-util-9.2.jar external/asm-util-9.2.jar ================================================ FILE: plugins/graaljs/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/graaljs/src/org/graalvm/visualvm/modules/graaljs/Bundle.properties ================================================ OpenIDE-Module-Display-Category=Libraries OpenIDE-Module-Long-Description=\ A high performance implementation of the JavaScript programming language. \ Built on the GraalVM by Oracle Labs. OpenIDE-Module-Name=GraalJS OpenIDE-Module-Short-Description=GraalVM implementation of JavaScript ================================================ FILE: plugins/jconsole/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.jconsole. ================================================ FILE: plugins/jconsole/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.modules.jconsole/2 OpenIDE-Module-Install: org/graalvm/visualvm/modules/jconsole/Install.class OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/jconsole/Bundle.properties OpenIDE-Module-Specification-Version: 2.0 ================================================ FILE: plugins/jconsole/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/jconsole/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=51f7c3b0 build.xml.script.CRC32=b5cff0b2 build.xml.stylesheet.CRC32=79c3b980 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=51f7c3b0 nbproject/build-impl.xml.script.CRC32=604888e2 nbproject/build-impl.xml.stylesheet.CRC32=deb65f65 ================================================ FILE: plugins/jconsole/nbproject/project.properties ================================================ # # Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. javac.source=1.5 cp.extra=${tools.jar}:${nbjdk.home}/lib/jconsole.jar license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Luis-Miguel Alventosa module.javadoc.packages=org.graalvm.visualvm.modules.jconsole.* ================================================ FILE: plugins/jconsole/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.jconsole org.graalvm.visualvm.application 2 2.0 org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.tools 2 2.0 org.netbeans.modules.options.api 1 1.5.1 org.openide.awt 6.11.1.1 org.openide.modules 7.3 org.openide.util 9.8 org.openide.util.lookup 8.3.1 org.openide.util.ui 9.8 org.openide.windows 6.18.1 ================================================ FILE: plugins/jconsole/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/jconsole/src/com/sun/tools/jconsole/JConsoleContext.java ================================================ /* * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.jconsole; import javax.management.MBeanServerConnection; import java.beans.PropertyChangeListener; import javax.swing.event.SwingPropertyChangeSupport; /** * {@code JConsoleContext} represents a JConsole connection to a target * application. *

* {@code JConsoleContext} notifies any {@code PropertyChangeListeners} * about the {@linkplain #CONNECTION_STATE_PROPERTY ConnectionState} * property change to {@link ConnectionState#CONNECTED CONNECTED} and * {@link ConnectionState#DISCONNECTED DISCONNECTED}. * The {@code JConsoleContext} instance will be the source for * any generated events. *

* * @since 1.6 */ public interface JConsoleContext { /** * The {@link ConnectionState ConnectionState} bound property name. */ public static String CONNECTION_STATE_PROPERTY = "connectionState"; // NOI18N /** * Values for the {@linkplain #CONNECTION_STATE_PROPERTY * ConnectionState} bound property. */ public enum ConnectionState { /** * The connection has been successfully established. */ CONNECTED, /** * No connection present. */ DISCONNECTED, /** * The connection is being attempted. */ CONNECTING } /** * Returns the {@link MBeanServerConnection MBeanServerConnection} for the * connection to an application. The returned * {@code MBeanServerConnection} object becomes invalid when * the connection state is changed to the * {@link ConnectionState#DISCONNECTED DISCONNECTED} state. * * @return the {@code MBeanServerConnection} for the * connection to an application. */ public MBeanServerConnection getMBeanServerConnection(); /** * Returns the current connection state. * @return the current connection state. */ public ConnectionState getConnectionState(); /** * Add a {@link java.beans.PropertyChangeListener PropertyChangeListener} * to the listener list. * The listener is registered for all properties. * The same listener object may be added more than once, and will be called * as many times as it is added. * If {@code listener} is {@code null}, no exception is thrown and * no action is taken. * * @param listener The {@code PropertyChangeListener} to be added */ public void addPropertyChangeListener(PropertyChangeListener listener); /** * Removes a {@link java.beans.PropertyChangeListener PropertyChangeListener} * from the listener list. This * removes a {@code PropertyChangeListener} that was registered for all * properties. If {@code listener} was added more than once to the same * event source, it will be notified one less time after being removed. If * {@code listener} is {@code null}, or was never added, no exception is * thrown and no action is taken. * * @param listener the {@code PropertyChangeListener} to be removed */ public void removePropertyChangeListener(PropertyChangeListener listener); } ================================================ FILE: plugins/jconsole/src/com/sun/tools/jconsole/JConsolePlugin.java ================================================ /* * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.jconsole; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import javax.swing.JPanel; import javax.swing.SwingWorker; /** * A JConsole plugin class. JConsole uses the * * service provider mechanism to search the JConsole plugins. * Users can provide their JConsole plugins in a jar file * containing a file named * *

 * META-INF/services/com.sun.tools.jconsole.JConsolePlugin
* *

This file contains one line for each plugin, for example, * *

 * com.sun.example.JTop
*

which is the fully qualified class name of the class implementing * {@code JConsolePlugin}. * *

To load the JConsole plugins in JConsole, run: * *

 * jconsole -pluginpath <plugin-path> 
* *

where <plugin-path> specifies the paths of JConsole * plugins to look up which can be a directory or a jar file. Multiple * paths are separated by the path separator character of the platform. * *

When a new JConsole window is created for a connection, * an instance of each {@code JConsolePlugin} will be created. * The {@code JConsoleContext} object is not available at its * construction time. * JConsole will set the {@link JConsoleContext} object for * a plugin after the plugin object is created. It will then * call its {@link #getTabs getTabs} method and add the returned * tabs to the JConsole window. * * @see * java.util.ServiceLoader * * @since 1.6 */ public abstract class JConsolePlugin { private volatile JConsoleContext context = null; private List listeners = null; /** * Constructor. */ protected JConsolePlugin() { } /** * Sets the {@link JConsoleContext JConsoleContext} object representing * the connection to an application. This method will be called * only once after the plugin is created and before the {@link #getTabs} * is called. The given {@code context} can be in any * {@link JConsoleContext#getConnectionState connection state} when * this method is called. * * @param context a {@code JConsoleContext} object */ public final synchronized void setContext(JConsoleContext context) { this.context = context; if (listeners != null) { for (PropertyChangeListener l : listeners) { context.addPropertyChangeListener(l); } // throw away the listener list listeners = null; } } /** * Returns the {@link JConsoleContext JConsoleContext} object representing * the connection to an application. This method may return null * if it is called before the {@link #setContext context} is initialized. * * @return the {@link JConsoleContext JConsoleContext} object representing * the connection to an application. */ public final JConsoleContext getContext() { return context; } /** * Returns the tabs to be added in JConsole window. *

* The returned map contains one entry for each tab * to be added in the tabbed pane in a JConsole window with * the tab name as the key * and the {@link JPanel} object as the value. * This method returns an empty map if no tab is added by this plugin. * This method will be called from the Event Dispatch Thread * once at the new connection time. * * @return a map of a tab name and a {@link JPanel} object * representing the tabs to be added in the JConsole window; * or an empty map. */ public abstract java.util.Map getTabs(); /** * Returns a {@link SwingWorker} to perform * the GUI update for this plugin at the same interval * as JConsole updates the GUI. *

* JConsole schedules the GUI update at an interval specified * for a connection. This method will be called at every * update to obtain a {@code SwingWorker} for each plugin. *

* JConsole will invoke the {@link SwingWorker#execute execute()} * method to schedule the returned {@code SwingWorker} for execution * if: *

    *
  • the SwingWorker object has not been executed * (i.e. the {@link SwingWorker#getState} method * returns {@link javax.swing.SwingWorker.StateValue#PENDING PENDING} * state); and
  • *
  • the SwingWorker object returned in the previous * update has completed the task if it was not null * (i.e. the {@link SwingWorker#isDone SwingWorker.isDone} method * returns true).
  • *
*
* Otherwise, SwingWorker object will not be scheduled to work. * *

* A plugin can schedule its own GUI update and this method * will return null. * * @return a SwingWorker to perform the GUI update; or * null. */ public abstract SwingWorker newSwingWorker(); /** * Dispose this plugin. This method is called by JConsole to inform * that this plugin will be discarded and that it should free * any resources that it has allocated. * The {@link #getContext JConsoleContext} can be in any * {@link JConsoleContext#getConnectionState connection state} when * this method is called. */ public void dispose() { // Default nop implementation } /** * Adds a {@link PropertyChangeListener PropertyChangeListener} * to the {@link #getContext JConsoleContext} object for this plugin. * This method is a convenient method for this plugin to register * a listener when the {@code JConsoleContext} object may or * may not be available. * *

For example, a plugin constructor can * call this method to register a listener to listen to the * {@link JConsoleContext.ConnectionState connectionState} * property changes and the listener will be added to the * {@link JConsoleContext#addPropertyChangeListener JConsoleContext} * object when it is available. * * @param listener The {@code PropertyChangeListener} to be added * * @throws NullPointerException if {@code listener} is {@code null}. */ public final void addContextPropertyChangeListener(PropertyChangeListener listener) { if (listener == null) { throw new NullPointerException("listener is null"); // NOI18N } if (context == null) { // defer registration of the listener until setContext() is called synchronized (this) { // check again if context is not set if (context == null) { // maintain a listener list to be added later if (listeners == null) { listeners = new ArrayList(); } listeners.add(listener); return; } } } context.addPropertyChangeListener(listener); } /** * Removes a {@link PropertyChangeListener PropertyChangeListener} * from the listener list of the {@link #getContext JConsoleContext} * object for this plugin. * If {@code listener} was never added, no exception is * thrown and no action is taken. * * @param listener the {@code PropertyChangeListener} to be removed * * @throws NullPointerException if {@code listener} is {@code null}. */ public final void removeContextPropertyChangeListener(PropertyChangeListener listener) { if (listener == null) { throw new NullPointerException("listener is null"); // NOI18N } if (context == null) { // defer registration of the listener until setContext() is called synchronized (this) { // check again if context is not set if (context == null) { if (listeners != null) { listeners.remove(listener); } return; } } } context.removePropertyChangeListener(listener); } } ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/Bundle.properties ================================================ # # Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Tools OpenIDE-Module-Long-Description=\ A plugin to enable using custom JConsole plugins in VisualVM. Use "Tools | Options | JConsole Plugins" to manage the JConsole plugins. OpenIDE-Module-Name=VisualVM-JConsole OpenIDE-Module-Short-Description=JConsole Plugins Container JMX_Not_Available=Data not available because JMX connection to the JMX agent could not be established. NoPluginInstalled=No JConsole plugin installed. InstallPluginHint=To install a JConsole plugin, click the Configure Plugins button and provide full path to the plugin file/directory. ConfigurePlugins=Configure Plugins JConsole_Plugins=JConsole Plugins ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/Install.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.jconsole; import org.openide.modules.ModuleInstall; /** * Manages a module's lifecycle. Remember that an installer is optional and * often not needed at all. * * @author Luis-Miguel Alventosa */ public class Install extends ModuleInstall { @Override public void restored() { JConsoleViewsSupport.sharedInstance(); } } ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/JConsolePluginWrapper.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.jconsole; import com.sun.tools.jconsole.JConsoleContext; import static com.sun.tools.jconsole.JConsoleContext.*; import com.sun.tools.jconsole.JConsoleContext.ConnectionState; import com.sun.tools.jconsole.JConsolePlugin; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.ui.components.Spacer; import org.graalvm.visualvm.modules.jconsole.options.JConsoleSettings; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import java.awt.BorderLayout; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; import java.util.Set; import java.util.logging.Logger; import javax.management.MBeanServerConnection; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.SwingWorker; import javax.swing.Timer; import javax.swing.event.SwingPropertyChangeSupport; import org.netbeans.api.options.OptionsDisplayer; import org.openide.awt.Mnemonics; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; class JConsolePluginWrapper { private static final Logger LOGGER = Logger.getLogger(JConsolePluginWrapper.class.getName()); private ServiceLoader pluginService; private JComponent jconsoleView; private VMPanel vmPanel; JConsolePluginWrapper(Application application) { JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application); if (jmxModel == null || jmxModel.getConnectionState() != JmxModel.ConnectionState.CONNECTED) { JTextArea textArea = new JTextArea(); textArea.setBorder(BorderFactory.createEmptyBorder(25, 9, 9, 9)); textArea.setEditable(false); textArea.setLineWrap(true); textArea.setWrapStyleWord(true); textArea.setText(NbBundle.getMessage(JConsolePluginWrapper.class, "JMX_Not_Available")); // NOI18N jconsoleView = textArea; } else { boolean availablePlugins = getPlugins().iterator().hasNext(); if (availablePlugins) { vmPanel = new VMPanel(application, this, new ProxyClient(jmxModel)); vmPanel.connect(); JPanel panel = new JPanel(new BorderLayout()); panel.setOpaque(false); panel.add(new JLabel(" "), BorderLayout.NORTH); // NOI18N panel.add(vmPanel, BorderLayout.CENTER); jconsoleView = panel; } else { GridBagConstraints c; JPanel hintPanel = new JPanel(new GridBagLayout()); hintPanel.setOpaque(false); hintPanel.setBorder(BorderFactory.createEmptyBorder(25, 9, 9, 9)); JLabel hintLabel = new JLabel(NbBundle.getMessage( JConsolePluginWrapper.class, "NoPluginInstalled")); // NOI18N hintLabel.setFont(hintLabel.getFont().deriveFont(Font.BOLD)); c = new GridBagConstraints(); c.gridy = 0; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.NONE; c.insets = new Insets(0, 0, 0, 0); hintPanel.add(hintLabel, c); JTextArea hintArea = new JTextArea(); hintArea.setEnabled(false); hintArea.setEditable(false); hintArea.setLineWrap(true); hintArea.setWrapStyleWord(true); hintArea.setDisabledTextColor(hintArea.getForeground()); hintArea.setOpaque(false); hintArea.setText(NbBundle.getMessage( JConsolePluginWrapper.class, "InstallPluginHint")); // NOI18N c = new GridBagConstraints(); c.gridy = 1; c.weightx = 1; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(5, 0, 0, 0); hintPanel.add(hintArea, c); JButton optionsButton = new JButton() { protected void fireActionPerformed(ActionEvent event) { OptionsDisplayer.getDefault().open("JConsoleOptions"); // NOI18N } }; Mnemonics.setLocalizedText(optionsButton, NbBundle.getMessage( JConsolePluginWrapper.class, "ConfigurePlugins")); // NOI18N c = new GridBagConstraints(); c.gridy = 2; c.anchor = GridBagConstraints.EAST; c.fill = GridBagConstraints.NONE; c.insets = new Insets(10, 0, 0, 0); hintPanel.add(optionsButton, c); c = new GridBagConstraints(); c.gridy = 3; c.weighty = 1; c.anchor = GridBagConstraints.NORTHWEST; c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; hintPanel.add(Spacer.create(), c); jconsoleView = hintPanel; } } } JComponent getView() { return jconsoleView; } void releasePlugins() { if (vmPanel != null) { vmPanel.disconnect(); } } // Return a list of newly instantiated JConsolePlugin objects synchronized List getPlugins() { if (pluginService == null) { String pluginPath = JConsoleSettings.getDefault().getPluginsPath(); // First time loading and initializing the plugins initPluginService(pluginPath == null ? "" : pluginPath); // NOI18N } else { // Reload the plugin so that new instances will be created pluginService.reload(); } List plugins = new ArrayList(); for (JConsolePlugin p : pluginService) { plugins.add(p); } return plugins; } private void initPluginService(String pluginPath) { if (pluginPath.length() > 0) { try { ClassLoader pluginCL = new URLClassLoader( pathToURLs(pluginPath), JConsolePluginWrapper.class.getClassLoader()); ServiceLoader plugins = ServiceLoader.load(JConsolePlugin.class, pluginCL); // Validate all plugins for (JConsolePlugin p : plugins) { LOGGER.finer("JConsole plugin " + p.getClass().getName() + " loaded."); // NOI18N } pluginService = plugins; } catch (ServiceConfigurationError e) { // Error occurs during initialization of plugin LOGGER.warning("Fail to load JConsole plugin: " + e.getMessage()); // NOI18N LOGGER.throwing(JConsolePluginWrapper.class.getName(), "initPluginService", e); // NOI18N } catch (MalformedURLException e) { LOGGER.warning("Invalid JConsole plugin path: " + e.getMessage()); // NOI18N LOGGER.throwing(JConsolePluginWrapper.class.getName(), "initPluginService", e); // NOI18N } } if (pluginService == null) { initEmptyPlugin(); } } private void initEmptyPlugin() { ClassLoader pluginCL = new URLClassLoader(new URL[0], JConsolePluginWrapper.class.getClassLoader()); pluginService = ServiceLoader.load(JConsolePlugin.class, pluginCL); } /** * Utility method for converting a search path string to an array * of directory and JAR file URLs. * * @param path the search path string * @return the resulting array of directory and JAR file URLs */ private static URL[] pathToURLs(String path) throws MalformedURLException { String[] names = path.split(File.pathSeparator); URL[] urls = new URL[names.length + 1]; urls[0] = JConsolePluginWrapper.class.getProtectionDomain().getCodeSource().getLocation(); int count = 1; for (String f : names) { URL url = fileToURL(new File(f)); urls[count++] = url; } return urls; } /** * Returns the directory or JAR file URL corresponding to the specified * local file name. * * @param file the File object * @return the resulting directory or JAR file URL, or null if unknown */ private static URL fileToURL(File file) throws MalformedURLException { String name; try { name = file.getCanonicalPath(); } catch (IOException e) { name = file.getAbsolutePath(); } name = name.replace(File.separatorChar, '/'); if (!name.startsWith("/")) { // NOI18N name = "/" + name; // NOI18N } // If the file does not exist, then assume that it's a directory if (!file.isFile()) { name = name + "/"; // NOI18N } return new URL("file", "", name); // NOI18N } class ProxyClient implements JConsoleContext, PropertyChangeListener { private ConnectionState connectionState = ConnectionState.DISCONNECTED; // The SwingPropertyChangeSupport will fire events on the EDT private SwingPropertyChangeSupport propertyChangeSupport = new SwingPropertyChangeSupport(this, true); private volatile boolean isDead = true; private JmxModel jmxModel = null; private MBeanServerConnection server = null; ProxyClient(JmxModel jmxModel) { this.jmxModel = jmxModel; } private void setConnectionState(ConnectionState state) { ConnectionState oldState = this.connectionState; this.connectionState = state; propertyChangeSupport.firePropertyChange(CONNECTION_STATE_PROPERTY, oldState, state); } public ConnectionState getConnectionState() { return this.connectionState; } void connect() { setConnectionState(ConnectionState.CONNECTING); try { tryConnect(); setConnectionState(ConnectionState.CONNECTED); } catch (Exception e) { e.printStackTrace(); setConnectionState(ConnectionState.DISCONNECTED); } } private void tryConnect() throws IOException { jmxModel.addPropertyChangeListener(this); this.server = jmxModel.getMBeanServerConnection(); this.isDead = false; } public MBeanServerConnection getMBeanServerConnection() { return server; } synchronized void disconnect() { jmxModel.removePropertyChangeListener(this); // Set connection state to DISCONNECTED if (!isDead) { isDead = true; setConnectionState(ConnectionState.DISCONNECTED); } } boolean isDead() { return isDead; } boolean isConnected() { return !isDead(); } public void addPropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(listener); } public void propertyChange(PropertyChangeEvent evt) { String prop = evt.getPropertyName(); if (CONNECTION_STATE_PROPERTY.equals(prop)) { org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState newState = (org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState) evt.getNewValue(); setConnectionState(ConnectionState.valueOf(newState.name())); } } } class VMPanel extends JTabbedPane implements PropertyChangeListener { private Application application; private ProxyClient proxyClient; private Timer timer; private int updateInterval = JConsoleSettings.getDefault().getPolling() * 1000; private boolean wasConnected = false; // Each VMPanel has its own instance of the JConsolePlugin. // A map of JConsolePlugin to the previous SwingWorker. private Map> plugins = null; private boolean pluginTabsAdded = false; VMPanel(Application application, JConsolePluginWrapper wrapper, ProxyClient proxyClient) { this.application = application; this.proxyClient = proxyClient; plugins = new LinkedHashMap>(); for (JConsolePlugin p : wrapper.getPlugins()) { p.setContext(proxyClient); plugins.put(p, null); } // Start listening to connection state events // proxyClient.addPropertyChangeListener(this); } boolean isConnected() { return proxyClient.isConnected(); } // Call on EDT void connect() { if (isConnected()) { // Create plugin tabs if not done createPluginTabs(); // Start/Restart update timer on connect/reconnect startUpdateTimer(); } else { proxyClient.connect(); } } // Call on EDT void disconnect() { // Disconnect proxyClient.disconnect(); // Dispose JConsole plugins disposePlugins(plugins.keySet()); // Cancel pending update tasks // if (timer != null) { timer.stop(); } // Stop listening to connection state events // proxyClient.removePropertyChangeListener(this); } // Called on EDT public void propertyChange(PropertyChangeEvent ev) { String prop = ev.getPropertyName(); if (CONNECTION_STATE_PROPERTY.equals(prop)) { ConnectionState newState = (ConnectionState) ev.getNewValue(); switch (newState) { case CONNECTED: // Create tabs if not done createPluginTabs(); repaint(); // Start/Restart update timer on connect/reconnect startUpdateTimer(); break; case DISCONNECTED: disconnect(); break; } } } private void startUpdateTimer() { if (timer != null) { timer.stop(); } timer = new Timer(updateInterval, new ActionListener() { public void actionPerformed(ActionEvent e) { RequestProcessor.getDefault().post(new Runnable() { public void run() { update(); } }); } }); timer.setCoalesce(true); timer.setInitialDelay(0); timer.start(); } // Note: This method is called on a TimerTask thread. Any GUI manipulation // must be performed with invokeLater() or invokeAndWait(). private Object lockObject = new Object(); private void update() { synchronized (lockObject) { if (!isConnected()) { if (wasConnected) { disconnect(); } wasConnected = false; return; } else { wasConnected = true; } // Plugin GUI update for (JConsolePlugin p : plugins.keySet()) { SwingWorker sw = p.newSwingWorker(); SwingWorker prevSW = plugins.get(p); // Schedule SwingWorker to run only if the previous // SwingWorker has finished its task and it hasn't started. if (prevSW == null || prevSW.isDone()) { if (sw == null || sw.getState() == SwingWorker.StateValue.PENDING) { plugins.put(p, sw); if (sw != null) { RequestProcessor.getDefault().post(sw); } } } } } } private void createPluginTabs() { // Add plugin tabs if not done if (!pluginTabsAdded) { Set failedPlugins = new HashSet(); for (JConsolePlugin p : plugins.keySet()) { try { Map tabs = p.getTabs(); for (Map.Entry e : tabs.entrySet()) { addTab(e.getKey(), e.getValue()); } } catch (Throwable t) { // Error occurs during plugin tab creation. failedPlugins.add(p); LOGGER.warning("JConsole plugin " + p.getClass().getName() + " removed: Failed to create JConsole plugin tabs."); // NOI18N LOGGER.throwing(VMPanel.class.getName(), "createPluginTabs", t); // NOI18N } } // Remove plugins that failed to return the plugin tabs for (JConsolePlugin p : failedPlugins) { plugins.remove(p); } disposePlugins(failedPlugins); pluginTabsAdded = true; } } private void disposePlugins(Set pluginSet) { for (JConsolePlugin p : pluginSet) { try { p.dispose(); } catch (Throwable t) { // Best effort, ignore if plugin fails to cleanup itself. } } } } } ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/JConsoleView.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.jconsole; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; /** * @author Leif Samuelsson * @author Luis-Miguel Alventosa */ class JConsoleView extends DataSourceView { private static final String IMAGE_PATH = "org/graalvm/visualvm/modules/jconsole/ui/resources/jconsole.png"; // NOI18N private Application application; private JConsolePluginWrapper wrapper; public JConsoleView(Application application) { super(application, NbBundle.getMessage(JConsoleView.class, "JConsole_Plugins"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false); // NOI18N this.application = application; } @Override protected void removed() { wrapper.releasePlugins(); } protected DataViewComponent createComponent() { wrapper = new JConsolePluginWrapper(application); return new DataViewComponent( new DataViewComponent.MasterView(NbBundle.getMessage(JConsoleView.class, "JConsole_Plugins"), null, wrapper.getView()), //NOI18N new DataViewComponent.MasterViewConfiguration(true)); } } ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/JConsoleViewProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.jconsole; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.DataSourceViewProvider; import org.graalvm.visualvm.core.ui.DataSourceViewsManager; /** * * @author Jiri Sedlacek * @author Luis-Miguel Alventosa */ public class JConsoleViewProvider extends DataSourceViewProvider { protected boolean supportsViewFor(Application application) { return true; } protected DataSourceView createView(Application application) { return new JConsoleView(application); } public void initialize() { DataSourceViewsManager.sharedInstance().addViewProvider(this, Application.class); } } ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/JConsoleViewsSupport.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.jconsole; /** * * @author Luis-Miguel Alventosa */ public final class JConsoleViewsSupport { private static JConsoleViewsSupport sharedInstance; public static synchronized JConsoleViewsSupport sharedInstance() { if (sharedInstance == null) { sharedInstance = new JConsoleViewsSupport(); } return sharedInstance; } private JConsoleViewsSupport() { new JConsoleViewProvider().initialize(); } } ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/options/Bundle.properties ================================================ # # Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OptionsCategory_Name_JConsole=JConsole Plugins CAP_PluginsContainer=JConsole Plugins Container LAB_PollingPeriod=&Polling period\: LAB_PollingUnits=sec. LAB_PluginsPath=P&lugins path\: BTN_Add=&Add JAR/Folder BTN_Remove=&Remove BTN_MoveUp=Move &Up BTN_MoveDown=Move &Down FIL_PluginFileFilterDescr=JConsole plugin (*.jar or directory) MSG_ReopenTab=The application needs to be (re)opened for the changes to take effect. ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/options/JConsoleCustomizer.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.jconsole.options; import org.graalvm.visualvm.core.options.UISupport; import org.graalvm.visualvm.core.ui.components.SectionSeparator; import org.graalvm.visualvm.core.ui.components.Spacer; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.File; import javax.swing.JButton; import javax.swing.event.ChangeEvent; import javax.swing.filechooser.FileFilter; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; import javax.swing.event.ChangeListener; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import org.openide.awt.Mnemonics; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; /** * * @author Jiri Sedlacek */ public class JConsoleCustomizer extends JPanel { private boolean initialized; private PathController pluginsController; private JFileChooser pluginsChooser; private JConsoleOptionsPanelController controler; JConsoleCustomizer(JConsoleOptionsPanelController contr) { this.controler = contr; initComponents(); pluginsChooser = new JFileChooser(); pluginsChooser.setMultiSelectionEnabled(true); pluginsChooser.setFileFilter(new CustomizerFileFilter()); pluginsChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); ListDataListener listListener = new ListDataListener() { public void intervalAdded(ListDataEvent arg0) {} public void intervalRemoved(ListDataEvent arg0) {} public void contentsChanged(ListDataEvent arg0) { changed(); } }; pluginsController = new PathController(jList1, pathLabel, jButtonAddJar, pluginsChooser, jButtonRemove, jButtonMoveUp, jButtonMoveDown, listListener); pluginsController.setVisible(true); } synchronized void changed() { controler.changed(); } synchronized void load() { String plugins = JConsoleSettings.getDefault().getPluginsPath(); Integer polling = JConsoleSettings.getDefault().getPolling(); pluginsController.updateModel(plugins); pollingPeriodSpinner.setValue(polling); initialized = true; } synchronized void store() { if (!initialized) { return; } JConsoleSettings.getDefault().setPluginsPath(pluginsController.toString()); JConsoleSettings.getDefault().setPolling((Integer)pollingPeriodSpinner.getValue()); } void cancel() { } boolean valid() { return true; } private void initComponents() { GridBagConstraints c; setLayout(new GridBagLayout()); SectionSeparator pollingSection = UISupport.createSectionSeparator(NbBundle.getMessage( JConsoleCustomizer.class, "CAP_PluginsContainer")); // NOI18N c = new GridBagConstraints(); c.gridy = 0; c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(0, 0, 5, 0); add(pollingSection, c); JLabel pollingPeriodLabel = new JLabel(); Mnemonics.setLocalizedText(pollingPeriodLabel, NbBundle.getMessage( JConsoleCustomizer.class, "LAB_PollingPeriod")); // NOI18N c = new GridBagConstraints(); c.gridx = 0; c.gridy = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(3, 15, 3, 0); add(pollingPeriodLabel, c); pollingPeriodSpinner = new JSpinner(); pollingPeriodLabel.setLabelFor(pollingPeriodSpinner); pollingPeriodSpinner.setModel(new SpinnerNumberModel(4, 1, 99999, 1)); pollingPeriodSpinner.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { changed(); } }); c = new GridBagConstraints(); c.gridx = 1; c.gridy = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(3, 10, 3, 4); add(pollingPeriodSpinner, c); JLabel pollingUnitsLabel = new JLabel(); Mnemonics.setLocalizedText(pollingUnitsLabel, NbBundle.getMessage( JConsoleCustomizer.class, "LAB_PollingUnits")); // NOI18N c = new GridBagConstraints(); c.gridx = 2; c.gridy = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(3, 0, 3, 0); add(pollingUnitsLabel, c); pathLabel = new JLabel(); Mnemonics.setLocalizedText(pathLabel, NbBundle.getMessage( JConsoleCustomizer.class, "LAB_PluginsPath")); // NOI18N c = new GridBagConstraints(); c.gridx = 0; c.gridy = 2; c.anchor = GridBagConstraints.WEST; c.gridwidth = GridBagConstraints.REMAINDER; c.insets = new Insets(8, 15, 3, 0); add(pathLabel, c); jList1 = new JList(); pathLabel.setLabelFor(jList1); JScrollPane listScroll = new JScrollPane(jList1) { public Dimension getPreferredSize() { return new Dimension(super.getPreferredSize().width, 1); } }; c = new GridBagConstraints(); c.gridx = 0; c.gridy = 3; c.gridwidth = 3; c.gridheight = 4; c.weightx = 1; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.BOTH; c.insets = new Insets(0, 15, 3, 5); add(listScroll, c); jButtonAddJar = new JButton(); Mnemonics.setLocalizedText(jButtonAddJar, NbBundle.getMessage( JConsoleCustomizer.class, "BTN_Add")); // NOI18N c = new GridBagConstraints(); c.gridx = 4; c.gridy = 3; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(0, 5, 3, 0); add(jButtonAddJar, c); jButtonRemove = new JButton(); Mnemonics.setLocalizedText(jButtonRemove, NbBundle.getMessage( JConsoleCustomizer.class, "BTN_Remove")); // NOI18N c = new GridBagConstraints(); c.gridx = 4; c.gridy = 4; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(3, 5, 3, 0); add(jButtonRemove, c); jButtonMoveUp = new JButton(); Mnemonics.setLocalizedText(jButtonMoveUp, NbBundle.getMessage( JConsoleCustomizer.class, "BTN_MoveUp")); // NOI18N c = new GridBagConstraints(); c.gridx = 4; c.gridy = 5; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(3, 5, 3, 0); add(jButtonMoveUp, c); jButtonMoveDown = new JButton(); Mnemonics.setLocalizedText(jButtonMoveDown, NbBundle.getMessage( JConsoleCustomizer.class, "BTN_MoveDown")); // NOI18N c = new GridBagConstraints(); c.gridx = 4; c.gridy = 6; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(3, 5, 3, 0); add(jButtonMoveDown, c); c = new GridBagConstraints(); c.gridx = 0; c.gridy = 7; c.weighty = 1; c.anchor = GridBagConstraints.NORTHWEST; c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; add(Spacer.create(), c); // hintLabel JLabel hintLabel = new JLabel(); Mnemonics.setLocalizedText(hintLabel, NbBundle.getMessage( JConsoleCustomizer.class, "MSG_ReopenTab")); // NOI18N hintLabel.setIcon(ImageUtilities.loadImageIcon( "org/graalvm/visualvm/modules/jconsole/ui/resources/infoIcon.png", false)); // NOI18N) hintLabel.setIconTextGap(10); c = new GridBagConstraints(); c.gridx = 0; c.gridy = 8; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(3, 0, 0, 0); add(hintLabel, c); } private JButton jButtonAddJar; private JButton jButtonMoveDown; private JButton jButtonMoveUp; private JButton jButtonRemove; private JList jList1; private JLabel pathLabel; private JSpinner pollingPeriodSpinner; private static class CustomizerFileFilter extends FileFilter { public boolean accept(File f) { if (f != null) { if (f.isDirectory()) return true; return f.isFile() && f.getName().toLowerCase().endsWith(".jar"); // NOI18N } return false; } public String getDescription() { return NbBundle.getMessage(JConsoleCustomizer.class, "FIL_PluginFileFilterDescr"); // NOI18N } } } ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/options/JConsoleOptionsPanelController.java ================================================ /* * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.jconsole.options; import org.graalvm.visualvm.core.options.UISupport; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import javax.swing.JComponent; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.HelpCtx; import org.openide.util.Lookup; /** * @author Tomas Hurka */ @OptionsPanelController.TopLevelRegistration( id = "JConsoleOptions", categoryName = "#OptionsCategory_Name_JConsole", iconBase = "org/graalvm/visualvm/modules/jconsole/ui/resources/jconsole32.png", position = 6000 ) public final class JConsoleOptionsPanelController extends OptionsPanelController { private JConsoleCustomizer panel; private JComponent component; private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private boolean changed; public void update() { getPanel().load(); changed = false; } public void applyChanges() { getPanel().store(); changed = false; } public void cancel() { // need not do anything special, if no changes have been persisted yet } public boolean isValid() { return getPanel().valid(); } public boolean isChanged() { return changed; } public HelpCtx getHelpCtx() { return null; // new HelpCtx("...ID") if you have a help set } public JComponent getComponent(Lookup masterLookup) { return getComponent(); } public void addPropertyChangeListener(PropertyChangeListener l) { pcs.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { pcs.removePropertyChangeListener(l); } private JConsoleCustomizer getPanel() { if (panel == null) { panel = new JConsoleCustomizer(this); } return panel; } private JComponent getComponent() { if (component == null) { component = UISupport.createScrollableContainer(getPanel()); } return component; } void changed() { if (!changed) { changed = true; pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true); } pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null); } } ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/options/JConsoleSettings.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.jconsole.options; import java.util.prefs.Preferences; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.openide.util.NbPreferences; public class JConsoleSettings implements ChangeListener { private static final String PROP_POLLING = "POLLING"; // NOI18N private static final String PROP_PLUGINSPATH = "PLUGINS"; // NOI18N private Preferences pref; private static JConsoleSettings INSTANCE; JConsoleSettings() { pref = NbPreferences.forModule(JConsoleSettings.class); } public static synchronized JConsoleSettings getDefault() { if (INSTANCE == null) { INSTANCE = new JConsoleSettings(); } return INSTANCE; } public void stateChanged(ChangeEvent e) { } public String getPluginsPath() { return pref.get(PROP_PLUGINSPATH, null); } public void setPluginsPath(String value) { pref.put(PROP_PLUGINSPATH, value); } public Integer getPolling() { return pref.getInt(PROP_POLLING, 4); } public void setPolling(Integer polling) { pref.putInt(PROP_POLLING, polling); } } ================================================ FILE: plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/options/PathController.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.jconsole.options; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.Enumeration; import java.util.StringTokenizer; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.ListModel; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.openide.windows.WindowManager; /** * * @author Jean-Francois Denise */ public class PathController implements ActionListener, ListSelectionListener, ListDataListener { private JList l; private JButton add; private JButton remove; private JButton up; private JButton down; private JFileChooser chooser; private DefaultListModel model; private JLabel label; private ListDataListener lstnr; public PathController(JList l, JLabel label, JButton add, JFileChooser chooser, JButton remove, JButton up, JButton down, ListDataListener lstnr) { this(l, label, createModel(""), add, chooser, remove, up, down, lstnr); // NOI18N } public PathController(JList l, JLabel label, String items, JButton add, JFileChooser chooser, JButton remove, JButton up, JButton down, ListDataListener lstnr) { this(l, label, createModel(items), add, chooser, remove, up, down, lstnr); } /** Creates a new instance of PathController */ public PathController(JList l, JLabel label, DefaultListModel model, JButton add, JFileChooser chooser, JButton remove, JButton up, JButton down, ListDataListener lstnr) { this.l = l; this.label = label; this.model = model; this.add = add; this.remove = remove; this.up = up; this.down = down; this.chooser = chooser; this.lstnr = lstnr; l.setModel(model); if (model != null) { model.addListDataListener(this); } add.setActionCommand("add");// NOI18N remove.setActionCommand("remove");// NOI18N up.setActionCommand("up");// NOI18N down.setActionCommand("down");// NOI18N add.addActionListener(this); remove.addActionListener(this); up.addActionListener(this); down.addActionListener(this); l.addListSelectionListener(this); remove.setEnabled(false); up.setEnabled(false); down.setEnabled(false); } public void setEnabled(boolean b) { l.setEnabled(b); label.setEnabled(b); add.setEnabled(b); remove.setEnabled(remove.isEnabled() && b); up.setEnabled(up.isEnabled() && b); down.setEnabled(down.isEnabled() && b); } public void setVisible(boolean b) { l.setVisible(b); label.setVisible(b); add.setVisible(b); remove.setVisible(b); up.setVisible(b); down.setVisible(b); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("add")) {// NOI18N int returnVal = chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()); if (returnVal == JFileChooser.APPROVE_OPTION) { File[] selection = chooser.getSelectedFiles(); int size = selection.length; int end = l.getModel().getSize(); for (int i = 0; i < size; i++) { String path = selection[i].getAbsolutePath(); if (!model.contains(path)) { model.add(end + i, path); } } } return; } if (e.getActionCommand().equals("remove")) {// NOI18N Object[] values = l.getSelectedValues(); for (int i = 0; i < values.length; i++) { model.removeElement(values[i]); } if (model.getSize() == 0) { up.setEnabled(false); down.setEnabled(false); remove.setEnabled(false); } l.setSelectedIndex(0); } if (e.getActionCommand().equals("up")) {// NOI18N int selectedI = l.getSelectedIndex(); Object selected = l.getSelectedValue(); int newIndex = selectedI - 1; Object previous = model.getElementAt(newIndex); model.setElementAt(selected, newIndex); model.setElementAt(previous, selectedI); l.setSelectedIndex(newIndex); return; } if (e.getActionCommand().equals("down")) {// NOI18N int selectedI = l.getSelectedIndex(); Object selected = l.getSelectedValue(); int newIndex = selectedI + 1; Object next = model.getElementAt(newIndex); model.setElementAt(selected, newIndex); model.setElementAt(next, selectedI); l.setSelectedIndex(newIndex); return; } } // return the list of selected items @Override public String toString() { Enumeration pluginsPath = model.elements(); StringBuffer buffer = new StringBuffer(); while (pluginsPath.hasMoreElements()) { Object path = pluginsPath.nextElement(); buffer.append(path.toString()); if (pluginsPath.hasMoreElements()) { buffer.append(File.pathSeparator); } } return buffer.toString(); } public synchronized void updateModel(String items) { if (items == null) { return; } ListModel m = l.getModel(); if (m != null) { m.removeListDataListener(this); } model = createModel(items); model.addListDataListener(this); l.setModel(model); } public static DefaultListModel createModel(String items) { StringTokenizer tk = new StringTokenizer(items, File.pathSeparator); DefaultListModel model = new DefaultListModel(); while (tk.hasMoreTokens()) { String path = tk.nextToken(); model.addElement(path); } return model; } public void valueChanged(ListSelectionEvent e) { int[] indices = l.getSelectedIndices(); if (indices.length != 1) { up.setEnabled(false); down.setEnabled(false); return; } int single = l.getSelectedIndex(); up.setEnabled(true); down.setEnabled(true); if (model.getSize() > 0) { remove.setEnabled(true); } if (single == 0) { up.setEnabled(false); if (model.getSize() == 1) { down.setEnabled(false); } } if (single == model.getSize() - 1) { down.setEnabled(false); } } public void intervalAdded(ListDataEvent arg0) { if (lstnr == null) { return; } lstnr.intervalAdded(arg0); } public void intervalRemoved(ListDataEvent arg0) { if (lstnr == null) { return; } lstnr.intervalRemoved(arg0); } public void contentsChanged(ListDataEvent arg0) { if (lstnr == null) { return; } lstnr.contentsChanged(arg0); } } ================================================ FILE: plugins/jfr.streaming/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.jfr.streaming. ================================================ FILE: plugins/jfr.streaming/manifest.mf ================================================ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: true OpenIDE-Module: org.graalvm.visualvm.jfr.streaming OpenIDE-Module-Install: org/graalvm/visualvm/jfr/streaming/Installer.class OpenIDE-Module-Java-Dependencies: Java > 17 OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/jfr/streaming/Bundle.properties OpenIDE-Module-Specification-Version: 1.7 ================================================ FILE: plugins/jfr.streaming/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/jfr.streaming/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=1ba7908e build.xml.script.CRC32=c2718227 build.xml.stylesheet.CRC32=15ca8a54@2.75.1 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=1ba7908e nbproject/build-impl.xml.script.CRC32=dc0dd611 nbproject/build-impl.xml.stylesheet.CRC32=1016842c@2.75.1 ================================================ FILE: plugins/jfr.streaming/nbproject/project.properties ================================================ is.eager=true javac.compilerargs=-Xlint -Xlint:-serial javac.source=17 license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Tomas Hurka nbm.needs.restart=true ================================================ FILE: plugins/jfr.streaming/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.jfr.streaming org.graalvm.visualvm.application 2 2.0 org.graalvm.visualvm.application.views 2 2.1 org.graalvm.visualvm.charts 2 2.1 org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.host 2 2.0 org.graalvm.visualvm.host.views 2 2.0 org.graalvm.visualvm.lib.jfluid 2 2.10 org.graalvm.visualvm.tools 2 2.0 org.openide.modules 7.60 org.openide.util 9.19 org.openide.util.lookup 8.46 org.openide.util.ui 9.20 ================================================ FILE: plugins/jfr.streaming/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/Bundle.properties ================================================ # # Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Tools OpenIDE-Module-Long-Description=\ Support for the JFR Streaming bundled with JDK 17 and newer (requires running VisualVM on JDK 17+) OpenIDE-Module-Name=VisualVM-JFR Streaming OpenIDE-Module-Short-Description=Support for the JFR streaming for JDK 17 and newer ================================================ FILE: plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/Installer.java ================================================ /* * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.jfr.streaming; import org.graalvm.visualvm.jfr.streaming.network.NetworkViewPluginProvider; import org.openide.modules.ModuleInstall; public class Installer extends ModuleInstall { @Override public void restored() { NetworkViewPluginProvider.initialize(); } } ================================================ FILE: plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/JFRStream.java ================================================ /* * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.jfr.streaming; import java.io.IOException; import java.time.Duration; import java.util.function.Consumer; import jdk.jfr.EventSettings; import jdk.jfr.Period; import jdk.jfr.StackTrace; import jdk.jfr.Threshold; import jdk.jfr.consumer.RecordedEvent; import jdk.management.jfr.RemoteRecordingStream; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.application.jvm.JvmFactory; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; /** * * @author Tomas Hurka */ public class JFRStream { private final RemoteRecordingStream rs; public static JFRStream getFor(Application app) throws IOException { Jvm jvm = JvmFactory.getJVMFor(app); String ver = jvm.getJavaVersion(); if (isJavaVersion(ver, "17") || isJavaVersion(ver, "18") || isJavaVersion(ver, "19") || isJavaVersion(ver, "20") || isJavaVersion(ver, "21") || isJavaVersion(ver, "22") || isJavaVersion(ver, "23") || isJavaVersion(ver, "24") || isJavaVersion(ver, "25")) { JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app); if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) { return new JFRStream(jmxModel); } } return null; } private JFRStream(JmxModel jmx) throws IOException { rs = new RemoteRecordingStream(jmx.getMBeanServerConnection()); } public void close() { rs.close(); } public JFREventSettings enable(String eventName) { EventSettings s = rs.enable(eventName); return new JFREventSettings(eventName, s); } public void onEvent(String eventName, Consumer action) { rs.onEvent(eventName, action); } public void onFlush(Runnable action) { rs.onFlush(action); } public void startAsync() { rs.startAsync(); } public class JFREventSettings { private final String eventName; private final EventSettings delegate; private JFREventSettings(String eventName, EventSettings s) { this.eventName = eventName; delegate = s; } public JFREventSettings withStackTrace() { return with(StackTrace.NAME, "true"); } public JFREventSettings withoutStackTrace() { return with(StackTrace.NAME, "false"); } public JFREventSettings withoutThreshold() { return withThreshold(null); } public JFREventSettings withPeriod(Duration duration) { return with(Period.NAME, getString(duration)); } public JFREventSettings withThreshold(Duration duration) { return with(Threshold.NAME, getString(duration)); } public JFREventSettings with(String name, String value) { delegate.with(eventName + "#" + name, value); return this; } private static String getString(Duration duration) { if (duration == null) { return "0 s"; } return duration.toNanos() + " ns"; } } private static final boolean isJavaVersion(String javaVersionProperty, String releaseVersion) { if (javaVersionProperty.equals(releaseVersion)) { return true; } if (javaVersionProperty.equals(releaseVersion + "-ea")) { return true; } if (javaVersionProperty.equals(releaseVersion + "-internal")) { return true; } if (javaVersionProperty.startsWith(releaseVersion + ".")) { return true; } return false; } } ================================================ FILE: plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/network/Bundle.properties ================================================ # # Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. # HTML-formatted: (< and > must remain!) LBL_Unknown=<unknown> LBL_Network=Network LBL_Heap=Heap LBL_Format_Kibps={0} Kibit/s LBL_Read_rate=Read rate LBL_Write_rate=Write rate LBL_Read_rate_leg=Read rate LBL_Write_rate_leg=Write rate ================================================ FILE: plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/network/NetworkModel.java ================================================ /* * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.jfr.streaming.network; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import jdk.jfr.consumer.RecordedEvent; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.options.GlobalPreferences; import org.graalvm.visualvm.host.Host; import org.graalvm.visualvm.jfr.streaming.JFRStream; /** * * @author Tomas Hurka */ final class NetworkModel { private static final String JFR_NETWORK_UTILIZATION = "jdk.NetworkUtilization"; // NOI18N private boolean initialized; private Host source; private JFRStream jfr; private boolean live; private final List listeners; private int chartCache = -1; private long timestamp = -1; private long readRate = -1; private long writeRate = -1; static NetworkModel create(Host host, JFRStream rs) { return new NetworkModel(host, rs); } DataSource getSource() { return source; } boolean isLive() { return live; } long getTimestamp() { return timestamp; } int getChartCache() { return chartCache; } long getReadRate() { return readRate; } long getWriteRate() { return writeRate; } synchronized void initialize() { if (initialized) { return; } initialized = true; initialize(source); } synchronized void cleanup() { listeners.clear(); if (!initialized) { return; } jfr.close(); jfr = null; } void addChangeListener(ChangeListener listener) { if (live) { listeners.add(listener); } } void removeChangeListener(ChangeListener listener) { if (live) { listeners.remove(listener); } } private void initialize(Host host) { GlobalPreferences preferences = GlobalPreferences.sharedInstance(); final int monitoredDataPoll = preferences.getMonitoredDataPoll(); chartCache = 60 * preferences.getMonitoredDataCache() / monitoredDataPoll; jfr.enable(JFR_NETWORK_UTILIZATION).withPeriod(Duration.ofSeconds(monitoredDataPoll)); jfr.onEvent(JFR_NETWORK_UTILIZATION, this::networkEvent); jfr.onFlush(this::jfrFlush); jfr.startAsync(); } private void jfrFlush() { SwingUtilities.invokeLater(() -> { fireChange(); timestamp = -1; }); } private void networkEvent(final RecordedEvent ev) { final Long[] values = getData(ev); if (values != null) { SwingUtilities.invokeLater(() -> { long time = ev.getStartTime().toEpochMilli(); if (time == timestamp) { readRate += values[0]; writeRate += values[1]; } else { fireChange(); readRate = values[0]; writeRate = values[1]; timestamp = time; } }); } } private Long[] getData(RecordedEvent ev) { if (live) { String iface = ev.getString("networkInterface"); // NOI18N long rRate = ev.getLong("readRate"); // NOI18N long wRate = ev.getLong("writeRate"); // NOI18N return new Long[]{rRate, wRate}; } return null; } private void fireChange() { if (timestamp == -1) return; final List list = new ArrayList<>(); synchronized (listeners) { list.addAll(listeners); } for (ChangeListener l : list) { l.stateChanged(new ChangeEvent(this)); } } private NetworkModel() { initialized = false; listeners = Collections.synchronizedList(new ArrayList<>()); } private NetworkModel(Host src, JFRStream rs) { this(); source = src; jfr = rs; live = true; } } ================================================ FILE: plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/network/NetworkViewComponent.java ================================================ /* * Copyright (c) 2022, 2022 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.jfr.streaming.network; import java.awt.BorderLayout; import java.text.MessageFormat; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.graalvm.visualvm.charts.ChartFactory; import org.graalvm.visualvm.charts.SimpleXYChartDescriptor; import org.graalvm.visualvm.charts.SimpleXYChartSupport; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer; import org.openide.util.NbBundle; /** * * @author Tomas Hurka */ class NetworkViewComponent extends JPanel { private static final String UNKNOWN = NbBundle.getMessage(NetworkViewComponent.class, "LBL_Unknown"); // NOI18N private boolean liveModel; private boolean networkMonitoringSupported; private String panelName; private SimpleXYChartSupport chartSupport; NetworkViewComponent(NetworkModel model) { initModels(model); initComponents(); } DataViewComponent.DetailsView getDetailsView() { return new DataViewComponent.DetailsView(panelName, null, 10, this, null); } private void refresh(NetworkModel model) { if (networkMonitoringSupported) { long readRate = model.getReadRate(); long writeRate = model.getWriteRate(); if (liveModel) { chartSupport.addValues(model.getTimestamp(), new long[]{readRate, writeRate}); } chartSupport.updateDetails(new String[]{formatKpbs(readRate / 1024), formatKpbs(writeRate / 1024)}); } } private String formatKpbs(long value) { String bytesFormat = NbBundle.getMessage(NetworkViewComponent.class, "LBL_Format_Kibps"); // NOI18N return MessageFormat.format(bytesFormat, new Object[]{chartSupport.formatDecimal(value)}); } private void initModels(final NetworkModel model) { liveModel = model.isLive(); networkMonitoringSupported = true; panelName = NbBundle.getMessage(NetworkViewComponent.class, "LBL_Network"); // NOI18N if (networkMonitoringSupported) { String READ_RATE = NbBundle.getMessage(NetworkViewComponent.class, "LBL_Read_rate"); // NOI18N String READ_RATE_LEG = NbBundle.getMessage(NetworkViewComponent.class, "LBL_Read_rate_leg"); // NOI18N String WRITE_RATE = NbBundle.getMessage(NetworkViewComponent.class, "LBL_Write_rate"); // NOI18N String WRITE_RATE_LEG = NbBundle.getMessage(NetworkViewComponent.class, "LBL_Write_rate_leg"); // NOI18N SimpleXYChartDescriptor chartDescriptor = SimpleXYChartDescriptor.bitsPerSec(10 * 1024 * 1024, false, model.getChartCache()); chartDescriptor.addLineItems(READ_RATE_LEG, WRITE_RATE_LEG); chartDescriptor.setDetailsItems(new String[]{READ_RATE, WRITE_RATE}); chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor); chartSupport.setZoomingEnabled(!liveModel); model.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { refresh(model); } }); } } private void initComponents() { setLayout(new BorderLayout()); setOpaque(false); if (networkMonitoringSupported) { add(chartSupport.getChart(), BorderLayout.CENTER); chartSupport.updateDetails(new String[]{UNKNOWN, UNKNOWN, UNKNOWN}); } else { add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM), BorderLayout.CENTER); } } } ================================================ FILE: plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/network/NetworkViewPlugin.java ================================================ /* * Copyright (c) 2022, 2022 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.jfr.streaming.network; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.ui.DataSourceViewPlugin; import org.graalvm.visualvm.core.ui.components.DataViewComponent; /** * * @author Tomas Hurka */ public class NetworkViewPlugin extends DataSourceViewPlugin { private final NetworkModel model; private NetworkViewComponent view; @Override public DataViewComponent.DetailsView createView(int location) { switch (location) { case DataViewComponent.TOP_LEFT: view = new NetworkViewComponent(model); return view.getDetailsView(); default: return null; } } @Override protected void willBeAdded() { model.initialize(); } @Override protected void removed() { model.cleanup(); } NetworkModel getModel() { return model; } NetworkViewPlugin(DataSource dataSource, NetworkModel model) { super(dataSource); this.model = model; } } ================================================ FILE: plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/network/NetworkViewPluginProvider.java ================================================ /* * Copyright (c) 2022, 2022 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.jfr.streaming.network; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.ui.DataSourceViewPlugin; import org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider; import org.graalvm.visualvm.host.Host; import org.graalvm.visualvm.host.views.HostViewsSupport; import org.graalvm.visualvm.jfr.streaming.JFRStream; /** * * @author Tomas Hurka */ public class NetworkViewPluginProvider extends DataSourceViewPluginProvider { private static final Logger LOGGER = Logger.getLogger(NetworkViewPluginProvider.class.getName()); private JFRStream rs; @Override protected DataSourceViewPlugin createPlugin(Host host) { return new NetworkViewPlugin(host, NetworkModel.create(host, rs)); } @Override protected boolean supportsPluginFor(Host t) { if (Host.LOCALHOST.equals(t)) { try { rs = JFRStream.getFor(Application.CURRENT_APPLICATION); } catch (IOException ex) { LOGGER.log(Level.WARNING, "supportsPluginFor", ex); } return rs != null; } return false; } private NetworkViewPluginProvider() { } public static void initialize() { HostViewsSupport.sharedInstance().getOverviewView(). registerPluginProvider(new NetworkViewPluginProvider()); } } ================================================ FILE: plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/threads/JFRThreadDataProvider.java ================================================ /* * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.jfr.streaming.threads; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.time.Instant; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.function.Consumer; import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.consumer.RecordedThread; import org.graalvm.visualvm.application.views.ApplicationThreadsResponseProvider; import org.graalvm.visualvm.jfr.streaming.JFRStream; import org.graalvm.visualvm.lib.jfluid.global.CommonConstants; import org.graalvm.visualvm.lib.jfluid.wireprotocol.MonitoredNumbersResponse; /** * * @author Tomas Hurka */ public class JFRThreadDataProvider implements ApplicationThreadsResponseProvider.ThreadMonitoredDataResponseProvider { private final JFRStream recordingStream; private final ThreadMXBean threadMXBean; private final List events; private final List newThreads; private final Set threadIdSet; JFRThreadDataProvider(JFRStream rs, ThreadMXBean tb) { recordingStream = rs; threadMXBean = tb; events = new ArrayList<>(); threadIdSet = new HashSet<>(); newThreads = new ArrayList<>(); } @Override public MonitoredNumbersResponse createThreadMonitoredDataResponse() { JFRNumbersResponse rp = new JFRNumbersResponse(); if (threadIdSet.isEmpty()) { threadIdSet.addAll(fillInThreadData(rp)); return rp; } synchronized (newThreads) { int[] newThreadsId = new int[newThreads.size()]; String[] newThreadsNames = new String[newThreads.size()]; String[] newThreadsClasses = new String[newThreads.size()]; int ntc = 0; for (JFRThread t : newThreads) { if (threadIdSet.add(t.threadId)) { newThreadsId[ntc] = (int) t.threadId; newThreadsNames[ntc] = t.name; newThreadsClasses[ntc] = ""; ntc++; } } if (ntc > 0) { rp.setDataOnNewThreads(ntc, newThreadsId, newThreadsNames, newThreadsClasses); } newThreads.clear(); } synchronized (events) { byte[] explicitStates = new byte[events.size()]; int[] explicitThreads = new int[events.size()]; long[] explicitTimeStamps = new long[events.size()]; int ePos = 0; for (int i = 0; i < events.size(); i++) { JFREvent te = events.get(i); if (te.status == CommonConstants.THREAD_STATUS_ZOMBIE) { if (!threadIdSet.remove(te.threadId)) { //unknown thread continue; } } explicitStates[ePos] = te.status; explicitThreads[ePos] = (int) te.threadId; explicitTimeStamps[ePos] = te.timeStamp; ePos++; } events.clear(); if (ePos < explicitStates.length) { byte[] msgExplicitStates = new byte[ePos]; System.arraycopy(explicitStates, 0, msgExplicitStates, 0, ePos); int[] msgExplicitThreads = new int[ePos]; System.arraycopy(explicitThreads, 0, msgExplicitThreads, 0, ePos); long[] msgExplicitTimeStamps = new long[ePos]; System.arraycopy(explicitTimeStamps, 0, msgExplicitTimeStamps, 0, ePos); rp.setExplicitDataOnThreads(msgExplicitThreads, msgExplicitStates, msgExplicitTimeStamps); } else { rp.setExplicitDataOnThreads(explicitThreads, explicitStates, explicitTimeStamps); } } return rp; } Consumer threadStart() { return (RecordedEvent e) -> { RecordedThread t = e.getThread(); addThreadStart(e.getStartTime(), t.getJavaThreadId(), t.getJavaName()); }; } Consumer threadEnd() { return (RecordedEvent e) -> { addThreadEnd(e.getThread().getJavaThreadId(), e.getStartTime()); }; } Consumer javaMonitorWait() { return (RecordedEvent e) -> { addWaitEvent(CommonConstants.THREAD_STATUS_WAIT, e); }; } Consumer javaMonitorEnter() { return (RecordedEvent e) -> { addWaitEvent(CommonConstants.THREAD_STATUS_MONITOR, e); }; } Consumer threadPark() { return (RecordedEvent e) -> { addWaitEvent(CommonConstants.THREAD_STATUS_PARK, e); }; } Consumer threadSleep() { return (RecordedEvent e) -> { addWaitEvent(CommonConstants.THREAD_STATUS_SLEEPING, e); }; } public void cleanup() { recordingStream.close(); } private void addThreadEnd(long id, Instant startTime) { addEvent(id, CommonConstants.THREAD_STATUS_ZOMBIE, startTime.toEpochMilli()); } private void addThreadStart(Instant startTime, long javaThreadId, String javaName) { synchronized (newThreads) { newThreads.add(new JFRThread(javaThreadId, javaName)); } } private void addWaitEvent(byte status, RecordedEvent e) { addWaitEvent(status, e.getThread().getJavaThreadId(), e.getStartTime(), e.getEndTime()); } private void addWaitEvent(byte status, long threadId, Instant startTime, Instant endTime) { addEvent(threadId, status, startTime.toEpochMilli()); addEvent(threadId, CommonConstants.THREAD_STATUS_RUNNING, endTime.toEpochMilli()); } private void addEvent(long threadId, byte status, long toEpochMilli) { synchronized (events) { events.add(new JFREvent(threadId, status, toEpochMilli)); } } private Set fillInThreadData(JFRNumbersResponse rp) { long[] currentThreadIds = threadMXBean.getAllThreadIds(); ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(currentThreadIds, 1); Set currentIdSet = new HashSet<>(currentThreadIds.length * 4 / 3); long timeStamps[] = {System.currentTimeMillis()}; int maxThreads = currentThreadIds.length; int tids[] = new int[maxThreads]; byte states[] = new byte[maxThreads]; int nNewThreads = 0; int newThreadsId[] = new int[currentThreadIds.length]; String[] newThreadsNames = new String[currentThreadIds.length]; String[] newThreadsClasses = new String[currentThreadIds.length]; for (int i = 0; i < currentThreadIds.length; i++) { ThreadInfo tinfo = threadInfos[i]; long threadId = currentThreadIds[i]; if (tinfo == null) { continue; } currentIdSet.add(threadId); newThreadsId[nNewThreads] = (int) threadId; newThreadsNames[nNewThreads] = tinfo.getThreadName(); newThreadsClasses[nNewThreads] = ""; tids[nNewThreads] = (int) threadId; states[nNewThreads] = getState(tinfo); nNewThreads++; } rp.setDataOnNewThreads(nNewThreads, newThreadsId, newThreadsNames, newThreadsClasses); rp.setDataOnThreads(nNewThreads, timeStamps.length, tids, timeStamps, states); return currentIdSet; } byte getState(ThreadInfo threadInfo) { Thread.State state = threadInfo.getThreadState(); switch (state) { case BLOCKED: return CommonConstants.THREAD_STATUS_MONITOR; case RUNNABLE: return CommonConstants.THREAD_STATUS_RUNNING; case TIMED_WAITING: case WAITING: StackTraceElement[] stack = threadInfo.getStackTrace(); if (stack.length > 0) { StackTraceElement el = stack[0]; if (isSleeping(el)) { return CommonConstants.THREAD_STATUS_SLEEPING; } if (isParked(el)) { return CommonConstants.THREAD_STATUS_PARK; } } return CommonConstants.THREAD_STATUS_WAIT; case TERMINATED: case NEW: return CommonConstants.THREAD_STATUS_ZOMBIE; } return CommonConstants.THREAD_STATUS_UNKNOWN; } boolean isSleeping(StackTraceElement element) { return Thread.class.getName().equals(element.getClassName()) && "sleep".equals(element.getMethodName()); // NOI18N } boolean isParked(StackTraceElement element) { String className = element.getClassName(); if ("jdk.internal.misc.Unsafe".equals(className) || "sun.misc.Unsafe".equals(className)) { // NOI18N return "park".equals(element.getMethodName()); // NOI18N } return false; } private class JFREvent { private long threadId; private byte status; private long timeStamp; private JFREvent(long id, byte st, long time) { threadId = id; status = st; timeStamp = time; } } private class JFRThread { private long threadId; private String name; private JFRThread(long id, String n) { threadId = id; name = n; } } class JFRNumbersResponse extends MonitoredNumbersResponse { private static final long[] dummyLong = new long[0]; JFRNumbersResponse() { super(dummyLong, CommonConstants.SERVER_RUNNING, CommonConstants.SERVER_PROGRESS_INDETERMINATE); setGCstartFinishData(dummyLong, dummyLong); } } } ================================================ FILE: plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/threads/ThreadMonitoringProvider.java ================================================ /* * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.jfr.streaming.threads; import java.io.IOException; import java.lang.management.ThreadMXBean; import java.util.logging.Level; import java.util.logging.Logger; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.views.ApplicationThreadsResponseProvider; import org.graalvm.visualvm.jfr.streaming.JFRStream; import org.openide.util.lookup.ServiceProvider; /** * * @author Tomas Hurka */ @ServiceProvider(service = ApplicationThreadsResponseProvider.class) public class ThreadMonitoringProvider implements ApplicationThreadsResponseProvider { private static final String JFR_THREAD_SLEEP = "jdk.ThreadSleep"; private static final String JFR_THREAD_PARK = "jdk.ThreadPark"; private static final String JFR_JAVA_MONITOR_ENTER = "jdk.JavaMonitorEnter"; private static final String JFR_JAVA_MONITOR_WAIT = "jdk.JavaMonitorWait"; private static final String JFR_THREAD_END = "jdk.ThreadEnd"; private static final String JFR_THREAD_START = "jdk.ThreadStart"; @Override public ThreadMonitoredDataResponseProvider getMonitoredDataResponseProvider(Application app, ThreadMXBean threadMXBean) { try { JFRStream rs = JFRStream.getFor(app); if (rs != null) { JFRThreadDataProvider rp = new JFRThreadDataProvider(rs, threadMXBean); rs.enable(JFR_THREAD_START); rs.enable(JFR_THREAD_END); rs.enable(JFR_JAVA_MONITOR_WAIT).withoutStackTrace(); rs.enable(JFR_JAVA_MONITOR_ENTER).withoutStackTrace(); rs.enable(JFR_THREAD_PARK).withoutStackTrace(); rs.enable(JFR_THREAD_SLEEP).withoutStackTrace(); rs.onEvent(JFR_THREAD_START, rp.threadStart()); rs.onEvent(JFR_THREAD_END, rp.threadEnd()); rs.onEvent(JFR_JAVA_MONITOR_WAIT, rp.javaMonitorWait()); rs.onEvent(JFR_JAVA_MONITOR_ENTER, rp.javaMonitorEnter()); rs.onEvent(JFR_THREAD_PARK, rp.threadPark()); rs.onEvent(JFR_THREAD_SLEEP, rp.threadSleep()); rs.startAsync(); return rp; } } catch (IOException ex) { Logger.getLogger(ThreadMonitoringProvider.class.getName()).log(Level.INFO, null, ex); } return null; } } ================================================ FILE: plugins/jolokia/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.jolokia. Downloading external binaries (external/ directory)... ================================================ FILE: plugins/jolokia/external/binaries-list ================================================ A8F24794CF3ABCBB54A2173EA11A45C80544EC75 org.jolokia:jolokia-client-jmx-adapter:2.2.2 27A76E0BDDEB96DDD14BE07189B3BF3BD0E2764F org.jolokia:jolokia-client-java:2.2.2 86CC1DAFC21A7214EEC1A3BB6910C865C378EC0A org.jolokia:jolokia-json:2.2.2 1BC42013E50B0065503821FD1FAD3D9B5C6FB9EB org.jolokia:jolokia-server-core:2.2.2 28D7DB48D69AAC91CD55CB914371044AC5A83910 org.jolokia:jolokia-service-serializer:2.2.2 1194890E6F56EC29177673F2F12D0B8E627DEC98 org.apache.httpcomponents:httpclient:4.5.14 51CF043C87253C9F58B539C9F7E44C8894223850 org.apache.httpcomponents:httpcore:4.4.16 B9FC14968D63A8B8A8A2C1885FE3E90564239708 commons-logging:commons-logging:1.3.4 973638B7149D333563584137EBF13A691BB60579 commons-codec:commons-codec:1.17.1 6C525AFAE116416E5EA3D02FAA70BBA833CF7178 org.jolokia:jolokia-client-kubernetes:2.2.2 2AA2FC58356CDCEA1C9C23B0F4A58EAF147B973C io.fabric8:kubernetes-client:6.13.4 5BCBB03DEB72DC59AE8F504207CB85B212B6E3F8 io.fabric8:kubernetes-client-api:6.13.4 9BB4038F7206BEAC6243FC603D7D8913F47064CE io.fabric8:kubernetes-model-core:6.13.4 7926CDB2A27C4517F67A57E84B0FDC52321BB881 io.fabric8:kubernetes-model-common:6.13.4 CA25C2F0E58571D4ED3F44B85EAEEFC006F39BC9 io.fabric8:kubernetes-model-gatewayapi:6.13.4 06D5724E29416153D3AA4F5EFA2DFBDB308C9416 io.fabric8:kubernetes-model-resource:6.13.4 BC68CC9AD92E3E6B48ACF518885B07AA94B5ADCF io.fabric8:kubernetes-model-rbac:6.13.4 81526FAD72FF4E9B633AD9763021E4180EEC7BD5 io.fabric8:kubernetes-model-admissionregistration:6.13.4 B8535726E5DE504086E7DAC2C775C24A1CD1A272 io.fabric8:kubernetes-model-apps:6.13.4 14672963E19477F584FB632A2DAF4CBB676AEDE4 io.fabric8:kubernetes-model-autoscaling:6.13.4 B7A04C7B3E5594B74877CF659C9F271197674833 io.fabric8:kubernetes-model-apiextensions:6.13.4 7EB4C0785834E1C9DB194C9DAFAB9AE1187FBAA0 io.fabric8:kubernetes-model-batch:6.13.4 30109AEE3D13E6D633ED974F3CD83761166394BE io.fabric8:kubernetes-model-certificates:6.13.4 B17C645531BF9F6BFE02E68982BC0E0D62DF15EB io.fabric8:kubernetes-model-coordination:6.13.4 2718498178FC1D79FF1E7169985CF3D2149AED6E io.fabric8:kubernetes-model-discovery:6.13.4 D716A15F8A23982FA72EA99A0017E16A3799BA67 io.fabric8:kubernetes-model-events:6.13.4 14359CF0EEACC9E63274C9D84C679A5923E5D60E io.fabric8:kubernetes-model-extensions:6.13.4 8D0CF291DDBA20C710F934544920830054617333 io.fabric8:kubernetes-model-flowcontrol:6.13.4 E9FCBE07E8E44CCD6A3B8A12B052DBF5979A7C9D io.fabric8:kubernetes-model-networking:6.13.4 D33C2F2C919194171E266D97F790B5CC5347E032 io.fabric8:kubernetes-model-metrics:6.13.4 9A73E7F0AEEF1BB6E1271092C53D4E0DB92E11BE io.fabric8:kubernetes-model-policy:6.13.4 0F9AA492F4CD8CB243126E2CD13F84C0FD8EF477 io.fabric8:kubernetes-model-scheduling:6.13.4 75D3331FBF04D9491649B6606C7997476BA83DFC io.fabric8:kubernetes-model-storageclass:6.13.4 A4FAD808C14CF3BB6B22B5C9BB3359CA9F0A140F io.fabric8:kubernetes-model-node:6.13.4 80229737F704B121A318BBA5D5DEACBCF395BC77 org.slf4j:slf4j-api:2.0.13 5213E62E87E62AC009D80AEB64C8240075BF078A org.snakeyaml:snakeyaml-engine:2.7 B4C7B8A9EA3F398116A75C146B982B22AFEBC4EE com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.17.1 3AF797A25458550A16BF89ACC8E4AB2B7F2BFCE0 org.yaml:snakeyaml:2.2 0969B0C3CB8C75D759E9A6C585C44C9B9F3A4F75 com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1 D3EBF0F291297649B4C8DC3ECC81D2EDDEDC100D io.fabric8:zjsonpatch:0.3.0 508DDD4587B39BF484C0AA71EADC8C6517397720 io.fabric8:kubernetes-httpclient-okhttp:6.13.4 D3E1CE1D2B3119ADF270B2D00D947BEB03FE3321 com.squareup.okhttp3:okhttp:3.12.12 BC28B5A964C8F5721EB58EE3F3C47A9BCBF4F4D8 com.squareup.okio:okio:1.15.0 D952189F6ABB148FF72AAB246AA8C28CF99B469F com.squareup.okhttp3:logging-interceptor:3.12.12 985D77751EBC7FCE5DB115A986BC9AA82F973F4A com.fasterxml.jackson.core:jackson-annotations:2.18.2 FB64CCAC5C27DCA8819418EB4E443A9F496D9EE7 com.fasterxml.jackson.core:jackson-core:2.18.2 DEEF8697B92141FB6CAF7AA86966CFF4EEC9B04F com.fasterxml.jackson.core:jackson-databind:2.18.2 ================================================ FILE: plugins/jolokia/external/commons-codec-1.17.1-license.txt ================================================ Name: Apache Commons Codec Description: General encoding/decoding algorithms (for example phonetic, base64, URL). Origin: https://commons.apache.org/proper/commons-codec/ Version: 1.17.1 License: Apache-2.0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: plugins/jolokia/external/commons-logging-1.3.4-license.txt ================================================ Name: Apache Jakarta Commons Logging Origin: Apache Software Foundation Version: 1.3.4 License: Apache-2.0 Description: Logging component URL: https://commons.apache.org/proper/commons-logging/ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: plugins/jolokia/external/httpclient-4.5.14-license.txt ================================================ Name: Apache Commons HttpClient Origin: Apache Software Foundation Version: 4.5.14 License: Apache-2.0 Description: HTTP client Origin: http://hc.apache.org/ Files: httpclient-4.5.14.jar, httpcore-4.4.16.jar Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: plugins/jolokia/external/jackson-2.18.2-license.txt ================================================ Name: Jackson Description: Jackson is a high-performance JSON processor for Java. License: Apache-2.0 Origin: https://github.com/FasterXML/jackson Version: 2.18.2 Files: jackson-annotations-2.18.2.jar, jackson-core-2.18.2.jar, jackson-databind-2.18.2.jar, jackson-dataformat-yaml-2.17.1.jar, jackson-datatype-jsr310-2.17.1.jar Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: plugins/jolokia/external/jolokia-client-kubernetes-2.2.2-license.txt ================================================ Name: Jolokia Description: Jolokia is remote JMX with JSON over HTTP. License: Apache-2.0 Origin: https://jolokia.org Version: 2.2.2 Files: jolokia-client-java-2.2.2.jar, jolokia-client-jmx-adapter-2.2.2.jar, jolokia-client-kubernetes-2.2.2.jar, jolokia-json-2.2.2.jar, jolokia-server-core-2.2.2.jar, jolokia-service-serializer-2.2.2.jar Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: plugins/jolokia/external/kubernetes-client-6.13.4-license.txt ================================================ Name: Kubernetes Client Description: Java client for Kubernetes and OpenShift. License: Apache-2.0 Origin: https://github.com/fabric8io/kubernetes-client/ Version: 6.13.4 Files: kubernetes-client-6.13.4.jar, kubernetes-client-api-6.13.4.jar, kubernetes-httpclient-okhttp-6.13.4.jar, kubernetes-model-admissionregistration-6.13.4.jar, kubernetes-model-apiextensions-6.13.4.jar, kubernetes-model-apps-6.13.4.jar, kubernetes-model-autoscaling-6.13.4.jar, kubernetes-model-batch-6.13.4.jar, kubernetes-model-certificates-6.13.4.jar, kubernetes-model-common-6.13.4.jar, kubernetes-model-coordination-6.13.4.jar, kubernetes-model-core-6.13.4.jar, kubernetes-model-discovery-6.13.4.jar, kubernetes-model-events-6.13.4.jar, kubernetes-model-extensions-6.13.4.jar, kubernetes-model-flowcontrol-6.13.4.jar, kubernetes-model-gatewayapi-6.13.4.jar, kubernetes-model-metrics-6.13.4.jar, kubernetes-model-networking-6.13.4.jar, kubernetes-model-node-6.13.4.jar, kubernetes-model-policy-6.13.4.jar, kubernetes-model-rbac-6.13.4.jar, kubernetes-model-resource-6.13.4.jar, kubernetes-model-scheduling-6.13.4.jar, kubernetes-model-storageclass-6.13.4.jar, zjsonpatch-0.3.0.jar Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: plugins/jolokia/external/okhttp-3.12.12-license.txt ================================================ Name: OkHttp Description: An HTTP+HTTP/2 client for Android and Java applications. License: Apache-2.0 Origin: https://github.com/square/okhttp/ Version: 3.12.12 Files: logging-interceptor-3.12.12.jar, okhttp-3.12.12.jar, okio-1.15.0.jar Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: plugins/jolokia/external/slf4j-api-2.0.13-license.txt ================================================ Name: SLF4J Version: 2.0.13 License: MIT-slf4j-22 Origin: https://www.slf4j.org/ Description: Simple Logging Facade for Java (SLF4J). Copyright (c) 2004-2024 QOS.ch Sarl (Switzerland) All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: plugins/jolokia/external/snakeyaml-2.2-license.txt ================================================ Name: snakeyaml Description: YAML 1.2 parser, reader, writer library Origin: GitHub Version: 2.2 License: Apache-2.0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: plugins/jolokia/external/snakeyaml-engine-2.7-license.txt ================================================ Name: snakeyaml-engine Description: YAML 1.2 parser, reader, writer library Origin: GitHub Version: 2.7 License: Apache-2.0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: plugins/jolokia/manifest.mf ================================================ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: true OpenIDE-Module-Java-Dependencies: Java > 11 OpenIDE-Module: org.graalvm.visualvm.modules.jolokia OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/jolokia/Bundle.properties OpenIDE-Module-Specification-Version: 2.2.2 ================================================ FILE: plugins/jolokia/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/jolokia/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=520d0fe2 build.xml.script.CRC32=f245468f build.xml.stylesheet.CRC32=a56c6a5b@2.73 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=78de761a nbproject/build-impl.xml.script.CRC32=e26352d3 nbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73 ================================================ FILE: plugins/jolokia/nbproject/project.properties ================================================ file.reference.jolokia-client-jmx-adapter-2.2.2.jar=external/jolokia-client-jmx-adapter-2.2.2.jar file.reference.jolokia-client-java-2.2.2.jar=external/jjolokia-client-java-2.2.2.jar file.reference.jolokia-json-2.2.2.jar=external/jolokia-json-2.2.2.jar file.reference.jolokia-server-core-2.2.2.jar=external/jolokia-server-core-2.2.2.jar file.reference.jolokia-service-serializer-2.2.2.jar=external/jolokia-service-serializer-2.2.2.jar file.reference.httpclient-4.5.14.jar=external/httpclient-4.5.14.jar file.reference.httpcore-4.4.16.jar=external/httpcore-4.4.16.jar file.reference.commons-logging-1.3.4.jar=external/commons-logging-1.3.4.jar file.reference.commons-codec-1.17.1.jar=external/commons-codec-1.17.1.jar file.reference.jolokia-client-kubernetes-2.2.2.jar=external/jolokia-client-kubernetes-2.2.2.jar file.reference.kubernetes-client-6.13.4.jar=external/kubernetes-client-6.13.4.jar file.reference.kubernetes-client-api-6.13.4.jar=external/kubernetes-client-api-6.13.4.jar file.reference.kubernetes-model-core-6.13.4.jar=external/kubernetes-model-core-6.13.4.jar file.reference.kubernetes-model-common-6.13.4.jar=external/kubernetes-model-common-6.13.4.jar file.reference.kubernetes-model-gatewayapi-6.13.4.jar=external/kubernetes-model-gatewayapi-6.13.4.jar file.reference.kubernetes-model-resource-6.13.4.jar=external/kubernetes-model-resource-6.13.4.jar file.reference.kubernetes-model-rbac-6.13.4.jar=external/kubernetes-model-rbac-6.13.4.jar file.reference.kubernetes-model-admissionregistration-6.13.4.jar=external/kubernetes-model-admissionregistration-6.13.4.jar file.reference.kubernetes-model-apps-6.13.4.jar=external/kubernetes-model-apps-6.13.4.jar file.reference.kubernetes-model-autoscaling-6.13.4.jar=external/kubernetes-model-autoscaling-6.13.4.jar file.reference.kubernetes-model-apiextensions-6.13.4.jar=external/kubernetes-model-apiextensions-6.13.4.jar file.reference.kubernetes-model-batch-6.13.4.jar=external/kubernetes-model-batch-6.13.4.jar file.reference.kubernetes-model-certificates-6.13.4.jar=external/kubernetes-model-certificates-6.13.4.jar file.reference.kubernetes-model-coordination-6.13.4.jar=external/kubernetes-model-coordination-6.13.4.jar file.reference.kubernetes-model-discovery-6.13.4.jar=external/kubernetes-model-discovery-6.13.4.jar file.reference.kubernetes-model-events-6.13.4.jar=external/kubernetes-model-events-6.13.4.jar file.reference.kubernetes-model-extensions-6.13.4.jar=external/kubernetes-model-extensions-6.13.4.jar file.reference.kubernetes-model-flowcontrol-6.13.4.jar=external/kubernetes-model-flowcontrol-6.13.4.jar file.reference.kubernetes-model-networking-6.13.4.jar=external/kubernetes-model-networking-6.13.4.jar file.reference.kubernetes-model-metrics-6.13.4.jar=external/kubernetes-model-metrics-6.13.4.jar file.reference.kubernetes-model-policy-6.13.4.jar=external/kubernetes-model-policy-6.13.4.jar file.reference.kubernetes-model-scheduling-6.13.4.jar=external/kubernetes-model-scheduling-6.13.4.jar file.reference.kubernetes-model-storageclass-6.13.4.jar=external/kubernetes-model-storageclass-6.13.4.jar file.reference.kubernetes-model-node-6.13.4.jar=external/kubernetes-model-node-6.13.4.jar file.reference.slf4j-api-2.0.13.jar=external/slf4j-api-2.0.13.jar file.reference.snakeyaml-engine-2.7.jar=external/snakeyaml-engine-2.7.jar file.reference.jackson-dataformat-yaml-2.17.1.jar=external/jackson-dataformat-yaml-2.17.1.jar file.reference.snakeyaml-2.2.jar=external/snakeyaml-2.2.jar file.reference.jackson-datatype-jsr310-2.17.1.jar=external/jackson-datatype-jsr310-2.17.1.jar file.reference.zjsonpatch-0.3.0.jar=external/zjsonpatch-0.3.0.jar file.reference.kubernetes-httpclient-okhttp-6.13.4.jar=external/kubernetes-httpclient-okhttp-6.13.4.jar file.reference.okhttp-3.12.12.jar=external/okhttp-3.12.12.jar file.reference.okio-1.15.0.jar=external/okio-1.15.0.jar file.reference.logging-interceptor-3.12.12.jar=external/logging-interceptor-3.12.12.jar file.reference.jackson-annotations-2.18.2.jar=external/jackson-annotations-2.18.2.jar file.reference.jackson-core-2.18.2.jar=external/jackson-core-2.18.2.jar file.reference.jackson-databind-2.18.2.jar=external/jackson-databind-2.18.2.jar is.eager=true license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Tomas Hurka nbm.needs.restart=true release.external/jolokia-client-jmx-adapter-2.2.2.jar=modules/ext/jolokia-client-jmx-adapter-2.2.2.jar release.external/jolokia-client-java-2.2.2.jar=modules/ext/jolokia-client-java-2.2.2.jar release.external/jolokia-json-2.2.2.jar=modules/ext/jolokia-json-2.2.2.jar release.external/jolokia-server-core-2.2.2.jar=modules/ext/jolokia-server-core-2.2.2.jar release.external/jolokia-service-serializer-2.2.2.jar=modules/ext/jolokia-service-serializer-2.2.2.jar release.external/httpclient-4.5.14.jar=modules/ext/httpclient-4.5.14.jar release.external/httpcore-4.4.16.jar=modules/ext/httpcore-4.4.16.jar release.external/commons-logging-1.3.4.jar=modules/ext/commons-logging-1.3.4.jar release.external/commons-codec-1.17.1.jar=modules/ext/commons-codec-1.17.1.jar release.external/jolokia-client-kubernetes-2.2.2.jar=modules/ext/jolokia-client-kubernetes-2.2.2.jar release.external/kubernetes-client-6.13.4.jar=modules/ext/kubernetes-client-6.13.4.jar release.external/kubernetes-client-api-6.13.4.jar=modules/ext/kubernetes-client-api-6.13.4.jar release.external/kubernetes-model-core-6.13.4.jar=modules/ext/kubernetes-model-core-6.13.4.jar release.external/kubernetes-model-common-6.13.4.jar=modules/ext/kubernetes-model-common-6.13.4.jar release.external/kubernetes-model-gatewayapi-6.13.4.jar=modules/ext/kubernetes-model-gatewayapi-6.13.4.jar release.external/kubernetes-model-resource-6.13.4.jar=modules/ext/kubernetes-model-resource-6.13.4.jar release.external/kubernetes-model-rbac-6.13.4.jar=modules/ext/kubernetes-model-rbac-6.13.4.jar release.external/kubernetes-model-admissionregistration-6.13.4.jar=modules/ext/kubernetes-model-admissionregistration-6.13.4.jar release.external/kubernetes-model-apps-6.13.4.jar=modules/ext/kubernetes-model-apps-6.13.4.jar release.external/kubernetes-model-autoscaling-6.13.4.jar=modules/ext/kubernetes-model-autoscaling-6.13.4.jar release.external/kubernetes-model-apiextensions-6.13.4.jar=modules/ext/kubernetes-model-apiextensions-6.13.4.jar release.external/kubernetes-model-batch-6.13.4.jar=modules/ext/kubernetes-model-batch-6.13.4.jar release.external/kubernetes-model-certificates-6.13.4.jar=modules/ext/kubernetes-model-certificates-6.13.4.jar release.external/kubernetes-model-coordination-6.13.4.jar=modules/ext/kubernetes-model-coordination-6.13.4.jar release.external/kubernetes-model-discovery-6.13.4.jar=modules/ext/kubernetes-model-discovery-6.13.4.jar release.external/kubernetes-model-events-6.13.4.jar=modules/ext/kubernetes-model-events-6.13.4.jar release.external/kubernetes-model-extensions-6.13.4.jar=modules/ext/kubernetes-model-extensions-6.13.4.jar release.external/kubernetes-model-flowcontrol-6.13.4.jar=modules/ext/kubernetes-model-flowcontrol-6.13.4.jar release.external/kubernetes-model-networking-6.13.4.jar=modules/ext/kubernetes-model-networking-6.13.4.jar release.external/kubernetes-model-metrics-6.13.4.jar=modules/ext/kubernetes-model-metrics-6.13.4.jar release.external/kubernetes-model-policy-6.13.4.jar=modules/ext/kubernetes-model-policy-6.13.4.jar release.external/kubernetes-model-scheduling-6.13.4.jar=modules/ext/kubernetes-model-scheduling-6.13.4.jar release.external/kubernetes-model-storageclass-6.13.4.jar=modules/ext/kubernetes-model-storageclass-6.13.4.jar release.external/kubernetes-model-node-6.13.4.jar=modules/ext/kubernetes-model-node-6.13.4.jar release.external/slf4j-api-2.0.13.jar=modules/ext/slf4j-api-2.0.13.jar release.external/snakeyaml-engine-2.7.jar=modules/ext/snakeyaml-engine-2.7.jar release.external/jackson-dataformat-yaml-2.17.1.jar=modules/ext/jackson-dataformat-yaml-2.17.1.jar release.external/snakeyaml-2.2.jar=modules/ext/snakeyaml-2.2.jar release.external/jackson-datatype-jsr310-2.17.1.jar=modules/ext/jackson-datatype-jsr310-2.17.1.jar release.external/zjsonpatch-0.3.0.jar=modules/ext/zjsonpatch-0.3.0.jar release.external/kubernetes-httpclient-okhttp-6.13.4.jar=modules/ext/kubernetes-httpclient-okhttp-6.13.4.jar release.external/okhttp-3.12.12.jar=modules/ext/okhttp-3.12.12.jar release.external/okio-1.15.0.jar=modules/ext/okio-1.15.0.jar release.external/logging-interceptor-3.12.12.jar=modules/ext/logging-interceptor-3.12.12.jar release.external/jackson-annotations-2.18.2.jar=modules/ext/jackson-annotations-2.18.2.jar release.external/jackson-core-2.18.2.jar=modules/ext/jackson-core-2.18.2.jar release.external/jackson-databind-2.18.2.jar=modules/ext/jackson-databind-2.18.2.jar javac.source=1.8 javac.compilerargs=-Xlint -Xlint:-serial ================================================ FILE: plugins/jolokia/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.jolokia ext/jolokia-client-jmx-adapter-2.2.2.jar external/jolokia-client-jmx-adapter-2.2.2.jar ext/jolokia-client-java-2.2.2.jar external/jolokia-client-java-2.2.2.jar ext/jolokia-json-2.2.2.jar external/jolokia-json-2.2.2.jar ext/jolokia-server-core-2.2.2.jar external/jolokia-server-core-2.2.2.jar ext/jolokia-service-serializer-2.2.2.jar external/jolokia-service-serializer-2.2.2.jar ext/httpclient-4.5.14.jar external/httpclient-4.5.14.jar ext/httpcore-4.4.16.jar external/httpcore-4.4.16.jar ext/commons-logging-1.3.4.jar external/commons-logging-1.3.4.jar ext/commons-codec-1.17.1.jar external/commons-codec-1.17.1.jar ext/jolokia-client-kubernetes-2.2.2.jar external/jolokia-client-kubernetes-2.2.2.jar ext/kubernetes-client-6.13.4.jar external/kubernetes-client-6.13.4.jar ext/kubernetes-client-api-6.13.4.jar external/kubernetes-client-api-6.13.4.jar ext/kubernetes-model-core-6.13.4.jar external/kubernetes-model-core-6.13.4.jar ext/kubernetes-model-common-6.13.4.jar external/kubernetes-model-common-6.13.4.jar ext/kubernetes-model-gatewayapi-6.13.4.jar external/kubernetes-model-gatewayapi-6.13.4.jar ext/kubernetes-model-resource-6.13.4.jar external/kubernetes-model-resource-6.13.4.jar ext/kubernetes-model-rbac-6.13.4.jar external/kubernetes-model-rbac-6.13.4.jar ext/kubernetes-model-admissionregistration-6.13.4.jar external/kubernetes-model-admissionregistration-6.13.4.jar ext/kubernetes-model-apps-6.13.4.jar external/kubernetes-model-apps-6.13.4.jar ext/kubernetes-model-autoscaling-6.13.4.jar external/kubernetes-model-autoscaling-6.13.4.jar ext/kubernetes-model-apiextensions-6.13.4.jar external/kubernetes-model-apiextensions-6.13.4.jar ext/kubernetes-model-batch-6.13.4.jar external/kubernetes-model-batch-6.13.4.jar ext/kubernetes-model-certificates-6.13.4.jar external/kubernetes-model-certificates-6.13.4.jar ext/kubernetes-model-coordination-6.13.4.jar external/kubernetes-model-coordination-6.13.4.jar ext/kubernetes-model-discovery-6.13.4.jar external/kubernetes-model-discovery-6.13.4.jar ext/kubernetes-model-events-6.13.4.jar external/kubernetes-model-events-6.13.4.jar ext/kubernetes-model-extensions-6.13.4.jar external/kubernetes-model-extensions-6.13.4.jar ext/kubernetes-model-flowcontrol-6.13.4.jar external/kubernetes-model-flowcontrol-6.13.4.jar ext/kubernetes-model-networking-6.13.4.jar external/kubernetes-model-networking-6.13.4.jar ext/kubernetes-model-metrics-6.13.4.jar external/kubernetes-model-metrics-6.13.4.jar ext/kubernetes-model-policy-6.13.4.jar external/kubernetes-model-policy-6.13.4.jar ext/kubernetes-model-scheduling-6.13.4.jar external/kubernetes-model-scheduling-6.13.4.jar ext/kubernetes-model-storageclass-6.13.4.jar external/kubernetes-model-storageclass-6.13.4.jar ext/kubernetes-model-node-6.13.4.jar external/kubernetes-model-node-6.13.4.jar ext/slf4j-api-2.0.13.jar external/slf4j-api-2.0.13.jar ext/snakeyaml-engine-2.7.jar external/snakeyaml-engine-2.7.jar ext/jackson-dataformat-yaml-2.17.1.jar external/jackson-dataformat-yaml-2.17.1.jar ext/snakeyaml-2.2.jar external/snakeyaml-2.2.jar ext/jackson-datatype-jsr310-2.17.1.jar external/jackson-datatype-jsr310-2.17.1.jar ext/zjsonpatch-0.3.0.jar external/zjsonpatch-0.3.0.jar ext/kubernetes-httpclient-okhttp-6.13.4.jar external/kubernetes-httpclient-okhttp-6.13.4.jar ext/okhttp-3.12.12.jar external/okhttp-3.12.12.jar ext/okio-1.15.0.jar external/okio-1.15.0.jar ext/logging-interceptor-3.12.12.jar external/logging-interceptor-3.12.12.jar ext/jackson-annotations-2.18.2.jar external/jackson-annotations-2.18.2.jar ext/jackson-core-2.18.2.jar external/jackson-core-2.18.2.jar ext/jackson-databind-2.18.2.jar external/jackson-databind-2.18.2.jar ================================================ FILE: plugins/jolokia/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/jolokia/src/org/graalvm/visualvm/modules/jolokia/Bundle.properties ================================================ OpenIDE-Module-Display-Category=Libraries OpenIDE-Module-Long-Description=\ Jolokia is a JMX-HTTP bridge giving an alternative to JSR-160 connectors. \ It is an agent based approach with support for many platforms. In addition \ to basic JMX operations it enhances JMX remoting with unique features like \ bulk requests and fine grained security policies. OpenIDE-Module-Name=Jolokia OpenIDE-Module-Short-Description=Jolokia is remote JMX with JSON over HTTP ================================================ FILE: plugins/jsyntaxpane-lib/build.xml ================================================ Builds, tests, and runs the project jsyntaxpane.lib. ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/APACHE-LICENSE-2.0.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/CHANGELOG.txt ================================================ Version 0.9.4 - IntelliSense additions * Adding IntelliSense to Java with simple List of selectable keywords * Added Toggle Comment Actions using Control SLASH * Fixed Issue 47. * Added Clojure, Scala, DOS Batch and 'nix bash support Version 0.9.3 - Start of scripts for the document: * Added new methods getLine() to SyntaxDocument * SyntaxDocument getIndexOf methods deprecated, use getMatchers instead * Added Line Numbering to Java * Added CaretMonitor Class * Merged Find And Replace dialogs into one. * Created SyntaxComponent interface and have all UI components implement that interface. DefaultSyntaxKit will use config.properties class to dynamically install these components. * Added Right Margin option and Single Color Selection Options * Added Python, C and C++ Support * Added Ruby Syntax Support * Fixed Issue 37 (NPE for LineNumbersRuler) * Fixed Issue 39 (Highlighting Tokens overrides selection highlights) * Fixed some JavaDoc comments. * Fixed Line Numbers being displayed for the height of the editor and now just for the actual available lines. * Fixed Margin typo in all project. Issue 43 * Changing Actions to be more configurable: * SyntaxActions renamed to ActionUtils * Removed all inner classes from SyntaxActions * Will create new SyntaxAction interface that will allow dynamic addition actions (in the addKeyActions of DefaultSyntaxKit * Added Text AA property to SyntaxView Version 0.9.2: * Fixing Java Indentation and Un-Indentattion Actions * Added and used (in the Tester) clearUndoes on the SyntaxDocument * Added Basic JFlex Syntax * Added getContentTypes to DefaultSyntaxKit to get all registered ContentTypes. This is now also used in the SyntaxTester instead of hardcoding the types. * Cleanup and optimization of Lexers by removing duplicate Java Code (replaced with Regex OR) * Removed calls to deprecated calls in SyntaxView * Modified the SyntaxDOcument to override the fireXXX methods and parse the document at that time instead of overriding the inserUpdate method. This fixes issue 24. * Added Groovy GString expression highlights * Removed getLanguages method from Lexer interface and implementations. * Added WARNING and ERROR TokenTypes and added their default styles. * Moved Keymaps and install methods to SyntaxKits instead of the Lexers * Removed deprecated methods from SyntaxActions class * Split SyntaxActions into new package and moved inner classes to the new package * Added Token HighLighter to Java * Added Pairs Highlighter to Java * Token class made immutable (all final fields) * Added Find and Replace Dialogs and Action to Java (mapped to C-F and C-H ) * Added pair matching to XML tags * Added CDATA matching and pair highlights for XML * Added Comment Pair Highlighting in XML * Fixed highlighting with selections so the selection always appears * Merged Find and Replace Dialogs into one * Fixed issue 33 (undable to add new line after final closing brace for Java) * Added Groovy Multi-Line strings and fixed Comments as Regex issue. * Fixes to empty find text field causing NPE Version 0.9.1 * Fixed empty strings in XML syntax Issue 29 * Fixed TAL lexer using incorrect package name Version 0.9.0 * Initial version after major overhaul ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/nbactions.xml ================================================ run jar process-classes org.codehaus.mojo:exec-maven-plugin:1.1:exec -classpath %classpath jsyntaxpane.SyntaxTester java debug jar process-classes org.codehaus.mojo:exec-maven-plugin:1.1:exec -Xdebug -Djava.compiler=none -Xnoagent -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath jsyntaxpane.SyntaxTester true java build * install true ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/pom.xml ================================================ 4.0.0 jsyntaxpane jsyntaxpane jar 0.9.4.1-visualvm jsyntaxpane A very simple to use and extend JEditorKit that supports few languages. The main goal is to make it easy to have nice looking Java Swing Editors with support for Syntax Highlighting. http://jsyntaxpane.googlecode.com/ The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0 repo http://jsyntaxpane.googlecode.com/svn/ jflex JFlex repository https://jflex.sourceforge.net/repo/ maven-compiler-plugin RELEASE 1.5 1.5 false org.apache.maven.plugins maven-jar-plugin jsyntaxpane.SyntaxTester jsyntaxpane true development ${pom.url} org.apache.maven.plugins maven-jar-plugin ../../release/modules/ext jsyntaxpane.SyntaxTester jsyntaxpane true development ${pom.url} de.jflex.maven.plugin maven-jflex-plugin generate ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/CompoundUndoManager.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.CompoundEdit; import javax.swing.undo.UndoManager; import javax.swing.undo.UndoableEdit; /** * A simple UndoManager that groups the Edits in each 0.5 second. If the time * difference between the current undo and the last one is less than 0.5 secs, * then the two edits are compound. * @author Ayman Al-Sairafi */ public class CompoundUndoManager extends UndoManager { /** * Delay between consequtive edits in ms where edits are added together. * If the delay is greater than this, then separate undo operations are * done, otherwise they are combined. */ public static final int IDLE_DELAY_MS = 500; long startMillis = 0; CompoundEdit comp = null; public CompoundUndoManager() { } @Override public synchronized boolean addEdit(UndoableEdit anEdit) { long now = System.currentTimeMillis(); if (comp == null) { comp = new CompoundEdit(); } comp.addEdit(anEdit); if (now - startMillis > IDLE_DELAY_MS) { comp.end(); super.addEdit(comp); comp = null; } startMillis = now; return true; } @Override public synchronized boolean canRedo() { commitCompound(); return super.canRedo(); } @Override public synchronized boolean canUndo() { commitCompound(); return super.canUndo(); } @Override public synchronized void discardAllEdits() { comp = null; super.discardAllEdits(); } @Override public synchronized void redo() throws CannotRedoException { commitCompound(); super.redo(); } @Override public synchronized void undo() throws CannotUndoException { commitCompound(); super.undo(); } private void commitCompound() { if (comp != null) { comp.end(); super.addEdit(comp); comp = null; } } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/DefaultLexer.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; /** * This is a default, and abstract implemenatation of a Lexer with * some utility methods that Lexers can implement. * * @author Ayman Al-Sairafi */ public abstract class DefaultLexer implements Lexer { protected int tokenStart; protected int tokenLength; /** * Helper method to create and return a new Token from of TokenType * @param type * @param tStart * @param tLength * @param newStart * @param newLength * @return */ protected Token token(TokenType type, int tStart, int tLength, int newStart, int newLength) { tokenStart = newStart; tokenLength = newLength; return new Token(type, tStart, tLength); } /** * Return the current matched token as a string. This is expensive * as it creates a new String object for the token. Use with care. * * @return */ protected CharSequence getTokenSrring() { return yytext(); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/DefaultSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; import java.awt.Color; import java.util.logging.Level; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.logging.Logger; import java.util.regex.Pattern; import javax.swing.JEditorPane; import javax.swing.KeyStroke; import javax.swing.text.DefaultEditorKit; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.JTextComponent; import javax.swing.text.Keymap; import javax.swing.text.TextAction; import javax.swing.text.View; import javax.swing.text.ViewFactory; import jsyntaxpane.actions.SyntaxAction; import jsyntaxpane.components.SyntaxComponent; import jsyntaxpane.util.Configuration; import jsyntaxpane.util.JarServiceProvider; /** * The DefaultSyntaxKit is the main entry to SyntaxPane. To use the package, just * set the EditorKit of the EditorPane to a new instance of this class. * * You need to pass a proper lexer to the class. * * @author ayman */ public class DefaultSyntaxKit extends DefaultEditorKit implements ViewFactory { public static Font DEFAULT_FONT; private static Set CONTENTS = new HashSet(); private static boolean initialized = false; private Lexer lexer; private static final Logger LOG = Logger.getLogger(DefaultSyntaxKit.class.getName()); public static final Pattern COMMA_REGEX = Pattern.compile("\\w+,\\w+"); private List editorComponents = new ArrayList(); private Map editorActions = new HashMap(); /** * Main Configuration of JSyntaxPane */ private static Configuration CONFIG; static { initKit(); } /** * Create a new Kit for the given language * @param lexer */ public DefaultSyntaxKit(Lexer lexer) { super(); this.lexer = lexer; } @Override public ViewFactory getViewFactory() { return this; } @Override public View create(Element element) { return new SyntaxView(element, CONFIG, this.getClass().getSimpleName()); } /** * Install the View on the given EditorPane. This is called by Swing and * can be used to do anything you need on the JEditorPane control. Here * I set some default Actions. * * @param editorPane */ @Override public void install(JEditorPane editorPane) { super.install(editorPane); editorPane.setFont(DEFAULT_FONT); Keymap km_parent = JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP); Keymap km_new = JTextComponent.addKeymap(null, km_parent); String kitName = this.getClass().getSimpleName(); Color caretColor = CONFIG.getPrefixColor(kitName, "CaretColor", Color.BLACK); editorPane.setCaretColor(caretColor); addSyntaxActions(km_new, ""); // shared actions addSyntaxActions(km_new, kitName); editorPane.setKeymap(km_new); // install the components to the editor: String[] components = CONFIG.getPrefixPropertyList(kitName, "Components"); for (String c : components) { try { @SuppressWarnings("unchecked") Class compClass = (Class) Class.forName(c); SyntaxComponent comp = compClass.newInstance(); comp.config(CONFIG, kitName); comp.install(editorPane); editorComponents.add(comp); } catch (InstantiationException ex) { LOG.log(Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { LOG.log(Level.SEVERE, null, ex); } catch (ClassNotFoundException ex) { LOG.log(Level.SEVERE, null, ex); } } } @Override public void deinstall(JEditorPane editorPane) { for (SyntaxComponent c : editorComponents) { c.deinstall(editorPane); } editorComponents.clear(); } /** * Add keyboard actions to this control using the Configuration we have * @param map * @param prefix */ public void addSyntaxActions(Keymap map, String prefix) { // look at all keys that either start with prefix.Action, or // that start with Action. Pattern splitter = CONFIG.getValueSeparator(prefix); Configuration actionsConf = CONFIG.subConfig(prefix, "Action."); for (String actionName : actionsConf.stringPropertyNames()) { String[] values = splitter.split( actionsConf.getProperty(actionName)); String actionClass = values[0]; SyntaxAction action = editorActions.get(actionClass); if (action == null) { action = createAction(actionClass); action.config(CONFIG, prefix, actionName); } String keyStrokeString = values[1]; KeyStroke ks = KeyStroke.getKeyStroke(keyStrokeString); // KeyEvent.VK_QUOTEDBL if (ks == null) { throw new IllegalArgumentException("Invalid KeyStroke: " + keyStrokeString); } TextAction ta = action.getAction(actionName); if(ta == null) { throw new IllegalArgumentException("Invalid ActionName: " + actionName); } map.addActionForKeyStroke(ks, ta); } } private SyntaxAction createAction(String actionClassName) { SyntaxAction action = null; try { Class clazz = JarServiceProvider.loadClass(actionClassName); action = (SyntaxAction) clazz.newInstance(); editorActions.put(actionClassName, action); } catch (InstantiationException ex) { throw new IllegalArgumentException("Cannot create action class: " + actionClassName, ex); } catch (IllegalAccessException ex) { throw new IllegalArgumentException("Cannot create action class: " + actionClassName, ex); } catch (ClassNotFoundException ex) { throw new IllegalArgumentException("Cannot create action class: " + actionClassName, ex); } catch (ClassCastException ex) { throw new IllegalArgumentException("Cannot create action class: " + actionClassName, ex); } return action; } /** * This is called by Swing to create a Document for the JEditorPane document * This may be called before you actually get a reference to the control. * We use it here to create a proper lexer and pass it to the * SyntaxDcument we return. * @return */ @Override public Document createDefaultDocument() { return new SyntaxDocument(lexer); } /** * This is called to initialize the list of Lexers we have. * You can call this at initialization, or it will be called when needed. * The method will also add the appropriate EditorKit classes to the * corresponding ContentType of the JEditorPane. After this is called, * you can simply call the editor.setCOntentType("text/java") on the * control and you will be done. */ public static void initKit() { // attempt to find a suitable default font CONFIG = new Configuration(JarServiceProvider.readProperties("jsyntaxpane.config")); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); String[] fonts = ge.getAvailableFontFamilyNames(); Arrays.sort(fonts); if (Arrays.binarySearch(fonts, "Courier new") >= 0) { DEFAULT_FONT = new Font("Courier New", Font.PLAIN, 12); } else if (Arrays.binarySearch(fonts, "Courier") >= 0) { DEFAULT_FONT = new Font("Courier", Font.PLAIN, 12); } else if (Arrays.binarySearch(fonts, "Monospaced") >= 0) { DEFAULT_FONT = new Font("Monospaced", Font.PLAIN, 13); } // read the Default Kits and their associated types Properties kitsForTypes = JarServiceProvider.readProperties("jsyntaxpane.kitsfortypes"); for (String type : kitsForTypes.stringPropertyNames()) { String classname = kitsForTypes.getProperty(type); registerContentType(type, classname); } initialized = true; } /** * Register the given content type to use the given class name as its kit * When this is called, an entry is added into the private HashMap of the * registered editors kits. This is needed so that the SyntaxPane library * has it's own registration of all the EditorKits * @param type * @param classname */ public static void registerContentType(String type, String classname) { JEditorPane.registerEditorKitForContentType(type, classname); CONTENTS.add(type); } /** * Return all the content types supported by this library. This will be the * content types in the file WEB-INF/services/resources/jsyntaxpane.kitsfortypes * @return sorted array of all registered content types */ public static String[] getContentTypes() { String[] types = CONTENTS.toArray(new String[0]); Arrays.sort(types); return types; } /** * returns the current config * @return */ public static Configuration getConfig() { if (!initialized) { initKit(); } return CONFIG; } /** * Merges the given properties with the defaults, which are read from the * Jar file * @param config */ public static void setConfig(Properties config) { DefaultSyntaxKit.CONFIG.putAll(config); } /** * Sets the given property to the given value. If the kit is not * initialized, then calls initKit * @param key * @param value */ public static void setProperty(String key, String value) { if (!initialized) { initKit(); } CONFIG.put(key, value); } /** * Return the property with the given key. If the kit is not * initialized, then calls initKit * Be careful when changing property as the default property may be used * @param key * @return value for given key */ public static String getProperty(String key) { if (!initialized) { initKit(); } return CONFIG.getProperty(key); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/Lexer.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; import java.io.Reader; /** * Lexers must implement these methods. These are used in the Tokenizer * * A Lexer should be tied to one document. * * @author Ayman Al-Sairafi */ public interface Lexer { /** * This will be called to reset the the lexer, generally whenever a * document is changed * @param reader */ public void yyreset(Reader reader); /** * This is called to return the next Token from the Input Reader * @return next token, or null if no more tokens. * @throws java.io.IOException */ public Token yylex() throws java.io.IOException; /** * Returns the character at position pos from the * matched text. * * It is equivalent to yytext().charAt(pos), but faster * * @param pos the position of the character to fetch. * A value from 0 to yylength()-1. * * @return the character at position pos */ public char yycharat(int pos); /** * Returns the length of the matched text region. */ public int yylength(); /** * Returns the text matched by the current regular expression. */ public String yytext(); } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxDocument.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; import java.io.CharArrayReader; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.event.DocumentEvent; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.text.BadLocationException; import javax.swing.text.Element; import javax.swing.text.PlainDocument; import javax.swing.text.Segment; import javax.swing.undo.UndoManager; /** * A document that supports being highlighted. The document maintains an * internal List of all the Tokens. The Tokens are updated using * a Lexer, passed to it during construction. * * @author Ayman Al-Sairafi */ public class SyntaxDocument extends PlainDocument { Lexer lexer; List tokens; UndoManager undo = new CompoundUndoManager(); public SyntaxDocument(Lexer lexer) { super(); putProperty(PlainDocument.tabSizeAttribute, 4); this.lexer = lexer; // Listen for undo and redo events addUndoableEditListener(new UndoableEditListener() { @Override public void undoableEditHappened(UndoableEditEvent evt) { if (evt.getEdit().isSignificant()) { undo.addEdit(evt.getEdit()); } } }); } /** * Parse the entire document and return list of tokens that do not already * exist in the tokens list. There may be overlaps, and replacements, * which we will cleanup later. * @return list of tokens that do not exist in the tokens field */ private void parse() { // if we have no lexer, then we must have no tokens... if (lexer == null) { tokens = null; return; } List toks = new ArrayList(getLength() / 10); long ts = System.nanoTime(); int len = getLength(); try { Segment seg = new Segment(); getText(0, getLength(), seg); CharArrayReader reader = new CharArrayReader(seg.array, seg.offset, seg.count); lexer.yyreset(reader); Token token; while ((token = lexer.yylex()) != null) { toks.add(token); } } catch (BadLocationException ex) { log.log(Level.SEVERE, null, ex); } catch (IOException ex) { // This will not be thrown from the Lexer log.log(Level.SEVERE, null, ex); } finally { if (log.isLoggable(Level.FINEST)) { log.finest(String.format("Parsed %d in %d ms, giving %d tokens\n", len, (System.nanoTime() - ts) / 1000000, toks.size())); } tokens = toks; } } @Override protected void fireChangedUpdate(DocumentEvent e) { parse(); super.fireChangedUpdate(e); } @Override protected void fireInsertUpdate(DocumentEvent e) { parse(); super.fireInsertUpdate(e); } @Override protected void fireRemoveUpdate(DocumentEvent e) { parse(); super.fireRemoveUpdate(e); } @Override protected void fireUndoableEditUpdate(UndoableEditEvent e) { parse(); super.fireUndoableEditUpdate(e); } /** * Replace the token with the replacement string * @param token * @param replacement */ public void replaceToken(Token token, String replacement) { try { replace(token.start, token.length, replacement, null); } catch (BadLocationException ex) { log.log(Level.WARNING, "unable to replace token: " + token, ex); } } /** * This class is used to iterate over tokens between two positions * */ class TokenIterator implements ListIterator { int start; int end; int ndx = 0; @SuppressWarnings("unchecked") private TokenIterator(int start, int end) { this.start = start; this.end = end; if (tokens != null && !tokens.isEmpty()) { Token token = new Token(TokenType.COMMENT, start, end - start); ndx = Collections.binarySearch((List) tokens, token); // we will probably not find the exact token... if (ndx < 0) { // so, start from one before the token where we should be... // -1 to get the location, and another -1 to go back.. ndx = (-ndx - 1 - 1 < 0) ? 0 : (-ndx - 1 - 1); Token t = tokens.get(ndx); // if the prev token does not overlap, then advance one if (t.end() <= start) { ndx++; } } } } @Override public boolean hasNext() { if (tokens == null) { return false; } if (ndx >= tokens.size()) { return false; } Token t = tokens.get(ndx); if (t.start >= end) { return false; } return true; } @Override public Token next() { return tokens.get(ndx++); } @Override public void remove() { throw new UnsupportedOperationException(); } public boolean hasPrevious() { if (tokens == null) { return false; } if (ndx <= 0) { return false; } Token t = tokens.get(ndx); if (t.end() <= start) { return false; } return true; } @Override public Token previous() { return tokens.get(ndx--); } @Override public int nextIndex() { return ndx + 1; } @Override public int previousIndex() { return ndx - 1; } @Override public void set(Token e) { throw new UnsupportedOperationException(); } @Override public void add(Token e) { throw new UnsupportedOperationException(); } } /** * Return an iterator of tokens between p0 and p1. * @param start start position for getting tokens * @param end position for last token * @return Iterator for tokens that overal with range from start to end */ public Iterator getTokens(int start, int end) { return new TokenIterator(start, end); } /** * Find the token at a given position. May return null if no token is * found (whitespace skipped) or if the position is out of range: * @param pos * @return */ public Token getTokenAt(int pos) { if (tokens == null || tokens.isEmpty() || pos > getLength()) { return null; } Token tok = null; Token tKey = new Token(TokenType.DEFAULT, pos, 1); @SuppressWarnings("unchecked") int ndx = Collections.binarySearch((List) tokens, tKey); if (ndx < 0) { // so, start from one before the token where we should be... // -1 to get the location, and another -1 to go back.. ndx = (-ndx - 1 - 1 < 0) ? 0 : (-ndx - 1 - 1); Token t = tokens.get(ndx); if ((t.start <= pos) && (pos <= t.end())) { tok = t; } } else { tok = tokens.get(ndx); } return tok; } /** * This is used to return the other part of a paired token in the document. * A paired part has token.pairValue <> 0, and the paired token will * have the negative of t.pairValue. * This method properly handles nestings of same pairValues, but overlaps * are not checked. * if The document does not contain a paired * @param t * @return the other pair's token, or null if nothing is found. */ public Token getPairFor(Token t) { if (t == null || t.pairValue == 0) { return null; } Token p = null; int ndx = tokens.indexOf(t); // w will be similar to a stack. The openners weght is added to it // and the closers are subtracted from it (closers are already negative) int w = t.pairValue; int direction = (t.pairValue > 0) ? 1 : -1; boolean done = false; int v = Math.abs(t.pairValue); while (!done) { ndx += direction; if (ndx < 0 || ndx >= tokens.size()) { break; } Token current = tokens.get(ndx); if (Math.abs(current.pairValue) == v) { w += current.pairValue; if (w == 0) { p = current; done = true; } } } return p; } /** * Perform an undo action, if possible */ public void doUndo() { if (undo.canUndo()) { undo.undo(); parse(); } } /** * Perform a redo action, if possible. */ public void doRedo() { if (undo.canRedo()) { undo.redo(); parse(); } } /** * Find the location of the given String in the document. returns -1 * if the search string is not found starting at position start * @param search The String to search for * @param start The beginning index of search * @return * @deprecated use {@link getMatcher} instead */ @Deprecated public int getIndexOf(String search, int start) { int flag = Pattern.LITERAL; Pattern pattern = Pattern.compile(search, flag); return getIndexOf(pattern, start); } /** * Find the next position that matches pattern in the document. * returns -1 if the pattern is not found. * @param pattern the regex pattern to find * @param start The beginning index of search * @return * @deprecated use {@link getMatcher} instead */ @Deprecated public int getIndexOf(Pattern pattern, int start) { int ndx = -1; if (pattern == null || getLength() == 0) { return -1; } try { Segment segment = new Segment(); getText(start, getLength() - start, segment); Matcher m = pattern.matcher(segment); if (m.find()) { // remember that the index is relative to the document, so // always add the start position to it ndx = m.start() + start; } } catch (BadLocationException ex) { log.log(Level.SEVERE, null, ex); } return ndx; } /** * Return a matcher that matches the given pattern on the entire document * @param pattern * @return matcher object */ public Matcher getMatcher(Pattern pattern) { return getMatcher(pattern, 0, getLength()); } /** * Return a matcher that matches the given pattern in the part of the * document starting at offset start. Note that the matcher will have * offset starting from start * * @param pattern * @param start * @return matcher that MUST be offset by start to get the proper * location within the document */ public Matcher getMatcher(Pattern pattern, int start) { return getMatcher(pattern, start, getLength() - start); } /** * Return a matcher that matches the given pattern in the part of the * document starting at offset start and ending at start + length. * Note that the matcher will have * offset starting from start * * @param pattern * @param start * @param length * @return matcher that MUST be offset by start to get the proper * location within the document */ public Matcher getMatcher(Pattern pattern, int start, int length) { Matcher matcher = null; if (getLength() == 0) { return null; } try { Segment seg = new Segment(); getText(start, length, seg); matcher = pattern.matcher(seg); } catch (BadLocationException ex) { log.log(Level.SEVERE, "Requested offset: " + ex.offsetRequested(), ex); } return matcher; } /** * This will discard all undoable edits */ public void clearUndos() { undo.discardAllEdits(); } /** * Gets the line at given position. The line returned will NOT include * the line terminator '\n' * @param pos Position (usually from text.getCaretPosition() * @return the STring of text at given position * @throws BadLocationException */ public String getLineAt(int pos) throws BadLocationException { Element e = getParagraphElement(pos); Segment seg = new Segment(); getText(e.getStartOffset(), e.getEndOffset() - e.getStartOffset(), seg); char last = seg.last(); if (last == '\n' || last == '\r') { return seg.subSequence(0, seg.length() - 1).toString(); } return seg.toString(); } /** * Deletes the line at given position * @param pos * @throws javax.swing.text.BadLocationException */ public void removeLineAt(int pos) throws BadLocationException { Element e = getParagraphElement(pos); remove(e.getStartOffset(), getElementLength(e)); } /** * Replace the line at given position with the given string, which can span * multiple lines * @param pos * @param newLines * @throws javax.swing.text.BadLocationException */ public void replaceLineAt(int pos, String newLines) throws BadLocationException { Element e = getParagraphElement(pos); replace(e.getStartOffset(), getElementLength(e), newLines, null); } /** * Helper method to get the length of an element and avoid getting * a too long element at the end of the document * @param e * @return */ private int getElementLength(Element e) { int end = e.getEndOffset(); if (end >= (getLength() - 1)) { end--; } return end - e.getStartOffset(); } /** * Gets the text without the comments. For example for the string * { // it's a comment this method will return "{ ". * @param aStart start of the text. * @param anEnd end of the text. * @return String for the line without comments (if exists). */ public synchronized String getUncommentedText(int aStart, int anEnd) { readLock(); StringBuilder result = new StringBuilder(); Iterator iter = getTokens(aStart, anEnd); while (iter.hasNext()) { Token t = iter.next(); if (TokenType.COMMENT != t.type && TokenType.COMMENT2 != t.type) { result.append(t.getText(this)); } } readUnlock(); return result.toString(); } /** * Returns the starting position of the line at pos * @param pos * @return starting position of the line */ public int getLineStartOffset(int pos) { return getParagraphElement(pos).getStartOffset(); } /** * Returns the end position of the line at pos. * Does a bounds check to ensure the returned value does not exceed * document length * @param pos * @return */ public int getLineEndOffset(int pos) { int end = 0; end = getParagraphElement(pos).getEndOffset(); if (end >= getLength()) { end = getLength(); } return end; } /** * Return the number of lines in this document * @return */ public int getLineCount() { Element e = getDefaultRootElement(); int cnt = e.getElementCount(); return cnt; } /** * Return the line number at given position. The line numbers are zero based * @param pos * @return */ public int getLineNumberAt(int pos) { int lineNr = getDefaultRootElement().getElementIndex(pos); return lineNr; } @Override public String toString() { return "SyntaxDocument(" + lexer + ", " + ((tokens == null) ? 0 : tokens.size()) + " tokens)@" + hashCode(); } // our logger instance... private static final Logger log = Logger.getLogger(SyntaxDocument.class.getName()); } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxStyle.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import javax.swing.text.Segment; import javax.swing.text.TabExpander; import javax.swing.text.Utilities; public final class SyntaxStyle { private Color color; private int fontStyle; public SyntaxStyle() { super(); } public SyntaxStyle(Color color, boolean bold, boolean italic) { super(); this.color = color; setBold(bold); setItalic(italic); } public SyntaxStyle(Color color, int fontStyle) { super(); this.color = color; this.fontStyle = fontStyle; } SyntaxStyle(String str) { String[] parts = str.split("\\s*,\\s*"); if (parts.length != 2) { throw new IllegalArgumentException("style not correct format: " + str); } this.color = new Color(Integer.decode(parts[0])); this.fontStyle = Integer.decode(parts[1]); } public boolean isBold() { return (fontStyle & Font.BOLD) != 0; } public void setBold(Boolean bold) { if (bold) { fontStyle |= Font.BOLD; } else { int mask = -1 ^ Font.BOLD; fontStyle = (fontStyle & (mask)); } } public String getColorString() { return String.format("0x%06x", color.getRGB() & 0x00ffffff); } public void setColorString(String color) { this.color = Color.decode(color); } public Boolean isItalic() { return (fontStyle & Font.ITALIC) != 0; } public void setItalic(Boolean italic) { if (italic) { fontStyle |= Font.ITALIC; } else { fontStyle = (fontStyle & (-1 ^ Font.ITALIC)); } } public int getFontStyle() { return fontStyle; } public Color getColor() { return color; } /** * Draw text. This can directly call the Utilities.drawTabbedText. * Sub-classes can override this method to provide any other decorations. * @param segment - the source of the text * @param x - the X origin >= 0 * @param y - the Y origin >= 0 * @param graphics - the graphics context * @param e - how to expand the tabs. If this value is null, tabs will be * expanded as a space character. * @param startOffset - starting offset of the text in the document >= 0 * @return */ public int drawText(Segment segment, int x, int y, Graphics graphics, TabExpander e, int startOffset) { graphics.setFont(graphics.getFont().deriveFont(getFontStyle())); FontMetrics fontMetrics = graphics.getFontMetrics(); int a = fontMetrics.getAscent(); int h = a + fontMetrics.getDescent(); int w = Utilities.getTabbedTextWidth(segment, fontMetrics, 0, e, startOffset); int rX = x - 1; int rY = y - a; int rW = w + 2; int rH = h; if ((getFontStyle() & 0x10) != 0) { graphics.setColor(Color.decode("#EEEEEE")); graphics.fillRect(rX, rY, rW, rH); } graphics.setColor(getColor()); x = Utilities.drawTabbedText(segment, x, y, graphics, e, startOffset); if ((getFontStyle() & 0x8) != 0) { graphics.setColor(Color.RED); graphics.drawRect(rX, rY, rW, rH); } return x; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxStyles.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.logging.Logger; import javax.swing.text.Segment; import javax.swing.text.TabExpander; import jsyntaxpane.util.JarServiceProvider; /** * The STyles to use for each TokenType. The defaults are created here, and * then the resource META-INF/services/syntaxstyles.properties is read and * merged. You can also pass a properties instance and merge your prefered * styles into the default styles * * @author Ayman */ public class SyntaxStyles { /** * You can call the mergeStyles method with a Properties file to customize * the existing styles. Any existing styles will be overwritten by the * styles you provide. * @param styles */ public void mergeStyles(Properties styles) { for (String token : styles.stringPropertyNames()) { String stv = styles.getProperty(token); try { TokenType tt = TokenType.valueOf(token); SyntaxStyle tokenStyle = new SyntaxStyle(stv); put(tt, tokenStyle); } catch (IllegalArgumentException ex) { LOG.warning("illegal token type or style for: " + token); } } } Map styles; private static SyntaxStyles instance = createInstance(); private static final Logger LOG = Logger.getLogger(SyntaxStyles.class.getName()); private static SyntaxStyle DEFAULT_STYLE = new SyntaxStyle(Color.BLACK, Font.PLAIN); private SyntaxStyles() { } /** * Create default styles * @return */ private static SyntaxStyles createInstance() { SyntaxStyles syntaxstyles = new SyntaxStyles(); Properties styles = JarServiceProvider.readProperties(SyntaxStyles.class); syntaxstyles.mergeStyles(styles); return syntaxstyles; } public static SyntaxStyles getInstance() { return instance; } public void put(TokenType type, SyntaxStyle style) { if (styles == null) { styles = new HashMap(); } styles.put(type, style); } /** * Set the graphics font and others to the style for the given token * @param g * @param type * @deprecated */ @Deprecated public void setGraphicsStyle(Graphics g, TokenType type) { Font c = g.getFont(); SyntaxStyle ss = styles.get(type); if (ss != null) { g.setFont(g.getFont().deriveFont(ss.getFontStyle())); g.setColor(ss.getColor()); } else { g.setFont(g.getFont().deriveFont(Font.PLAIN)); g.setColor(Color.BLACK); } } /** * Return the style for the given TokenType * @param type * @return */ public SyntaxStyle getStyle(TokenType type) { if (styles.containsKey(type)) { return styles.get(type); } else { return DEFAULT_STYLE; } } /** * Draw the given Token. This will simply find the proper SyntaxStyle for * the TokenType and then asks the proper Style to draw the text of the * Token. * @param segment * @param x * @param y * @param graphics * @param e * @param token * @return */ public int drawText(Segment segment, int x, int y, Graphics graphics, TabExpander e, Token token) { SyntaxStyle s = getStyle(token.type); return s.drawText(segment, x, y, graphics, e, token.start); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxTester.form ================================================

================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxTester.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; import java.awt.event.ItemEvent; import java.awt.Rectangle; import javax.swing.DefaultComboBoxModel; import javax.swing.text.BadLocationException; import jsyntaxpane.actions.CaretMonitor; public class SyntaxTester extends javax.swing.JFrame { /** Creates new form Tester */ public SyntaxTester() { DefaultSyntaxKit.initKit(); initComponents(); jCmbLangs.setModel(new DefaultComboBoxModel(DefaultSyntaxKit.getContentTypes())); // jEdtTest.setContentType(jCmbLangs.getItemAt(0).toString()); jCmbLangs.setSelectedItem("text/java"); new CaretMonitor(jEdtTest, lblCaretPos); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ // //GEN-BEGIN:initComponents private void initComponents() { lblCaretPos = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); jEdtTest = new javax.swing.JEditorPane(); lblToken = new javax.swing.JLabel(); jCmbLangs = new javax.swing.JComboBox(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("JSyntaxPane Tester"); lblCaretPos.setText("Caret Position"); jEdtTest.setContentType(""); jEdtTest.setFont(new java.awt.Font("Monospaced", 0, 13)); jEdtTest.addCaretListener(new javax.swing.event.CaretListener() { public void caretUpdate(javax.swing.event.CaretEvent evt) { jEdtTestCaretUpdate(evt); } }); jScrollPane1.setViewportView(jEdtTest); lblToken.setFont(new java.awt.Font("Courier New", 0, 12)); lblToken.setText("Token under cursor"); jCmbLangs.setMaximumRowCount(20); jCmbLangs.setFocusable(false); jCmbLangs.addItemListener(new java.awt.event.ItemListener() { public void itemStateChanged(java.awt.event.ItemEvent evt) { jCmbLangsItemStateChanged(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(lblToken, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 612, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addComponent(jCmbLangs, 0, 231, Short.MAX_VALUE) .addGap(262, 262, 262) .addComponent(lblCaretPos, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 612, Short.MAX_VALUE)) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE) .addGap(2, 2, 2) .addComponent(lblToken, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jCmbLangs, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblCaretPos, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)) .addContainerGap()) ); pack(); }// //GEN-END:initComponents private void jEdtTestCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_jEdtTestCaretUpdate if (jEdtTest.getDocument() instanceof SyntaxDocument) { SyntaxDocument sDoc = (SyntaxDocument) jEdtTest.getDocument(); Token t = sDoc.getTokenAt(evt.getDot()); if (t != null) { try { String tData = sDoc.getText(t.start, Math.min(t.length, 40)); if (t.length > 40) { tData += "..."; } lblToken.setText(t.toString() + ": " + tData); } catch (BadLocationException ex) { // should not happen.. and if it does, just ignore it System.err.println(ex); ex.printStackTrace(); } } } }//GEN-LAST:event_jEdtTestCaretUpdate private void jCmbLangsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jCmbLangsItemStateChanged if (evt.getStateChange() == ItemEvent.SELECTED) { String lang = jCmbLangs.getSelectedItem().toString(); // save the state of the current JEditorPane, as it's Document is about // to be replaced. String t = jEdtTest.getText(); int caretPosition = jEdtTest.getCaretPosition(); Rectangle visibleRectangle = jEdtTest.getVisibleRect(); // install a new DefaultSyntaxKit on the JEditorPane for the requested language. jEdtTest.setContentType(lang); // restore the state of the JEditorPane - note that installing a new // EditorKit causes the Document to be recreated. SyntaxDocument sDoc = (SyntaxDocument) jEdtTest.getDocument(); jEdtTest.setText(t); sDoc.clearUndos(); jEdtTest.setCaretPosition(caretPosition); jEdtTest.scrollRectToVisible(visibleRectangle); } }//GEN-LAST:event_jCmbLangsItemStateChanged /** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { new SyntaxTester().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JComboBox jCmbLangs; private javax.swing.JEditorPane jEdtTest; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JLabel lblCaretPos; private javax.swing.JLabel lblToken; // End of variables declaration//GEN-END:variables } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxView.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.text.BadLocationException; import javax.swing.text.Element; import javax.swing.text.PlainView; import javax.swing.text.Segment; import javax.swing.text.ViewFactory; import jsyntaxpane.util.Configuration; public class SyntaxView extends PlainView { public static final String PROPERTY_RIGHT_MARGIN_COLOR = "RightMarginColor"; public static final String PROPERTY_RIGHT_MARGIN_COLUMN = "RightMarginColumn"; public static final String PROPERTY_SINGLE_COLOR_SELECT = "SingleColorSelect"; public static final String PROPERTY_TEXTAA = "TextAA"; private static final Logger log = Logger.getLogger(SyntaxView.class.getName()); private SyntaxStyle DEFAULT_STYLE = SyntaxStyles.getInstance().getStyle(TokenType.DEFAULT); private final boolean singleColorSelect; private final int rightMarginColumn; private final Color rightMarginColor; private final Object textAAHint; /** * Construct a new view using the given configuration and prefix given * * @param element * @param config * @param prefix */ public SyntaxView(Element element, Configuration config, String prefix) { super(element); singleColorSelect = config.getPrefixBoolean(prefix, PROPERTY_SINGLE_COLOR_SELECT, false); rightMarginColor = new Color(config.getPrefixInteger(prefix, PROPERTY_RIGHT_MARGIN_COLOR, 0xFF7777)); rightMarginColumn = config.getPrefixInteger(prefix, PROPERTY_RIGHT_MARGIN_COLUMN, 0); String textaa = config.getPrefixProperty(prefix, PROPERTY_TEXTAA, "DEFAULT"); textAAHint = TEXT_AA_HINT_NAMES.get(textaa); } @Override protected int drawUnselectedText(Graphics graphics, int x, int y, int p0, int p1) { Graphics2D graphics2D = (Graphics2D) graphics; graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAAHint); Font saveFont = graphics.getFont(); Color saveColor = graphics.getColor(); SyntaxDocument doc = (SyntaxDocument) getDocument(); Segment segment = getLineBuffer(); // Draw the right margin first, if needed. This way the text overalys // the margin if (rightMarginColumn > 0) { int m_x = rightMarginColumn * graphics.getFontMetrics().charWidth('m'); int h = graphics.getFontMetrics().getHeight(); graphics.setColor(rightMarginColor); graphics.drawLine(m_x, y, m_x, y - h); } try { // Colour the parts Iterator i = doc.getTokens(p0, p1); int start = p0; while (i.hasNext()) { Token t = i.next(); // if there is a gap between the next token start and where we // should be starting (spaces not returned in tokens), then draw // it in the default type if (start < t.start) { doc.getText(start, t.start - start, segment); x = DEFAULT_STYLE.drawText(segment, x, y, graphics, this, start); } // t and s are the actual start and length of what we should // put on the screen. assume these are the whole token.... int l = t.length; int s = t.start; // ... unless the token starts before p0: if (s < p0) { // token is before what is requested. adgust the length and s l -= (p0 - s); s = p0; } // if token end (s + l is still the token end pos) is greater // than p1, then just put up to p1 if (s + l > p1) { l = p1 - s; } doc.getText(s, l, segment); x = SyntaxStyles.getInstance().drawText(segment, x, y, graphics, this, t); start = t.end(); } // now for any remaining text not tokenized: if (start < p1) { doc.getText(start, p1 - start, segment); x = DEFAULT_STYLE.drawText(segment, x, y, graphics, this, start); } } catch (BadLocationException ex) { System.err.println("Requested: " + ex.offsetRequested()); log.log(Level.SEVERE, null, ex); } finally { graphics.setFont(saveFont); graphics.setColor(saveColor); } return x; } @Override protected int drawSelectedText(Graphics graphics, int x, int y, int p0, int p1) throws BadLocationException { if (singleColorSelect) { if (rightMarginColumn > 0) { int m_x = rightMarginColumn * graphics.getFontMetrics().charWidth('m'); int h = graphics.getFontMetrics().getHeight(); graphics.setColor(rightMarginColor); graphics.drawLine(m_x, y, m_x, y - h); } return super.drawUnselectedText(graphics, x, y, p0, p1); } else { return drawUnselectedText(graphics, x, y, p0, p1); } } @Override protected void updateDamage(javax.swing.event.DocumentEvent changes, Shape a, ViewFactory f) { super.updateDamage(changes, a, f); java.awt.Component host = getContainer(); host.repaint(); } /** * The values for the string key for Text Anti-Aliasing */ private static Map TEXT_AA_HINT_NAMES = new HashMap(); static { TEXT_AA_HINT_NAMES.put("DEFAULT", RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); TEXT_AA_HINT_NAMES.put("GASP", RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); TEXT_AA_HINT_NAMES.put("HBGR", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR); TEXT_AA_HINT_NAMES.put("HRGB", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); TEXT_AA_HINT_NAMES.put("VBGR", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR); TEXT_AA_HINT_NAMES.put("VRGB", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR); TEXT_AA_HINT_NAMES.put("OFF", RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); TEXT_AA_HINT_NAMES.put("ON", RenderingHints.VALUE_TEXT_ANTIALIAS_ON); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/Token.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; import java.io.Serializable; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.text.BadLocationException; import javax.swing.text.Document; public class Token implements Serializable, Comparable { public final TokenType type; public final int start; public final int length; /** * the pair value to use if this token is one of a pair: * This is how it is used: * The openning part will have a positive number X * The closing part will have a negative number X * X should be unique for a pair: * e.g. for [ pairValue = +1 * for ] pairValue = -1 */ public final byte pairValue; /** * Constructs a new token * @param type * @param start * @param length */ public Token(TokenType type, int start, int length) { this.type = type; this.start = start; this.length = length; this.pairValue = 0; } /** * Construct a new part of pair token * @param type * @param start * @param length * @param pairValue */ public Token(TokenType type, int start, int length, byte pairValue) { this.type = type; this.start = start; this.length = length; this.pairValue = pairValue; } @Override public boolean equals(Object obj) { if (obj instanceof Object) { Token token = (Token) obj; return ((this.start == token.start) && (this.length == token.length) && (this.type.equals(token.type))); } else { return false; } } @Override public int hashCode() { return start; } @Override public String toString() { return String.format("%s (%d, %d) (%d)", type, start, length, pairValue); } @Override public int compareTo(Object o) { Token t = (Token) o; if (this.start != t.start) { return (this.start - t.start); } else if(this.length != t.length) { return (this.length - t.length); } else { return this.type.compareTo(t.type); } } /** * return the end position of the token. * @return start + length */ public int end() { return start + length; } /** * Get the text of the token from this document * @param doc * @return */ public String getText(Document doc) { String text = null; try { text = doc.getText(start, length); } catch (BadLocationException ex) { Logger.getLogger(Token.class.getName()).log(Level.SEVERE, null, ex); } return text; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/TokenType.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane; /** * These are the various token types supported by JSyntaxPane. * * @author ayman */ public enum TokenType { OPERATOR, // Language operators KEYWORD, // language reserved keywords KEYWORD2, // Other language reserved keywords, like C #defines IDENTIFIER, // identifiers, variable names, class names NUMBER, // numbers in various formats STRING, // String STRING2, // For highlighting meta chars within a String COMMENT, // comments COMMENT2, // special stuff within comments REGEX, // regular expressions REGEX2, // special chars within regular expressions TYPE, // Types, usually not keywords, but supported by the language TYPE2, // Types from standard libraries TYPE3, // Types for users DEFAULT, // any other text WARNING, // Text that should be highlighted as a warning ERROR // Text that signals an error } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ActionUtils.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.Component; import java.awt.Frame; import java.awt.Point; import java.awt.Rectangle; import java.awt.Window; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JComboBox; import javax.swing.MutableComboBoxModel; import javax.swing.SwingUtilities; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import javax.swing.text.PlainDocument; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.Token; /** * Various utility methods to work on JEditorPane and its SyntaxDocument * for use by Actions * * @author Ayman Al-Sairafi */ public class ActionUtils { /** * Perform Smart Indentation: pos must be on a line: this method will * use the previous lines indentation (number of spaces before any non-space * character or end of line) and return that as the prefix * @param line the line of text * @return */ public static String getIndent(String line) { if (line == null || line.length() == 0) { return ""; } int i = 0; while (i < line.length() && line.charAt(i) == ' ') { i++; } return line.substring(0, i); } /** * Return the lines that span the selection (split as an array of Strings) * if there is no selection then current line is returned. * * Note that the strings returned will not contain the terminating line feeds * * The text component will then have the full lines set as selection * @param target * @return String[] of lines spanning selection / or Dot */ public static String[] getSelectedLines(JTextComponent target) { String[] lines = null; try { PlainDocument pDoc = (PlainDocument) target.getDocument(); int start = pDoc.getParagraphElement(target.getSelectionStart()).getStartOffset(); int end; if (target.getSelectionStart() == target.getSelectionEnd()) { end = pDoc.getParagraphElement(target.getSelectionEnd()).getEndOffset(); } else { // if more than one line is selected, we need to subtract one from the end // so that we do not select the line with the caret and no selection in it end = pDoc.getParagraphElement(target.getSelectionEnd() - 1).getEndOffset(); } target.select(start, end); lines = pDoc.getText(start, end - start).split("\n"); target.select(start, end); } catch (BadLocationException ex) { Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, null, ex); lines = EMPTY_STRING_ARRAY; } return lines; } /** * Return the line of text at the TextComponent's current position * @param target * @return */ public static String getLine(JTextComponent target) { return getLineAt(target, target.getCaretPosition()); } /** * Return the line of text at the given position. The returned value may * be null. It will not contain the trailing new-line character. * @param target the text component * @param pos char position * @return */ public static String getLineAt(JTextComponent target, int pos) { String line = null; Document doc = target.getDocument(); if (doc instanceof PlainDocument) { PlainDocument pDoc = (PlainDocument) doc; int start = pDoc.getParagraphElement(pos).getStartOffset(); int end = pDoc.getParagraphElement(pos).getEndOffset(); try { line = doc.getText(start, end - start); if (line != null && line.endsWith("\n")) { line = line.substring(0, line.length() - 1); } } catch (BadLocationException ex) { Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, null, ex); } } return line; } /** * Returns the Frame that contains this component or null if the component * is not within a Window or the containing window is not a frame * @param comp * @return */ public static Frame getFrameFor(Component comp) { Window w = SwingUtilities.getWindowAncestor(comp); if (w != null && w instanceof Frame) { Frame frame = (Frame) w; return frame; } return null; } /** * Returns the the Token at pos as a String * @param doc * @param pos * @return */ public static String getTokenStringAt( SyntaxDocument doc, int pos) { String word = ""; Token t = doc.getTokenAt(pos); if (t != null) { try { word = doc.getText(t.start, t.length); } catch (BadLocationException ex) { Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, null, ex); } } return word; } /** * A helper function that will return the SyntaxDocument attached to the * given text component. Return null if the document is not a * SyntaxDocument, or if the text component is null * @param component * @return */ public static SyntaxDocument getSyntaxDocument(JTextComponent component) { if (component == null) { return null; } Document doc = component.getDocument(); if (doc instanceof SyntaxDocument) { return (SyntaxDocument) doc; } else { return null; } } /** * Gets the Line Number at the give position of the editor component. * The first line number is ZERO * @param editor * @param pos * @return line number * @throws javax.swing.text.BadLocationException */ public static int getLineNumber(JTextComponent editor, int pos) throws BadLocationException { if (getSyntaxDocument(editor) != null) { SyntaxDocument sdoc = getSyntaxDocument(editor); return sdoc.getLineNumberAt(pos); } else { Document doc = editor.getDocument(); return doc.getDefaultRootElement().getElementIndex(pos); } } /** * Gets the column number at given position of editor. The first column is * ZERO * @param editor * @param pos * @return the 0 based column number * @throws javax.swing.text.BadLocationException */ public static int getColumnNumber(JTextComponent editor, int pos) throws BadLocationException { Rectangle r = editor.modelToView(pos); int start = editor.viewToModel(new Point(0, r.y)); int column = pos - start; return column; } /** * Get the closest position within the document of the component that * has given line and column. * @param editor * @param line * @param column * @return the closest positon for the text component at given line and * column */ public static int getDocumentPosition(JTextComponent editor, int line, int column) { int lineHeight = editor.getFontMetrics(editor.getFont()).getHeight(); int charWidth = editor.getFontMetrics(editor.getFont()).charWidth('m'); int y = line * lineHeight; int x = column * charWidth; Point pt = new Point(x, y); int pos = editor.viewToModel(pt); return pos; } public static int getLineCount(JTextComponent pane) { SyntaxDocument sdoc = getSyntaxDocument(pane); if (sdoc != null) { return sdoc.getLineCount(); } int count = 0; try { int p = pane.getDocument().getLength() - 1; if (p > 0) { count = getLineNumber(pane, p); } } catch (BadLocationException ex) { Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, null, ex); } return count; } /** * Insert the given item into the combo box, and set it as first selected * item. If the item already exists, it is removed, so there are no * duplicates. * @param combo * @param item */ public static void insertIntoCombo(JComboBox combo, Object item) { MutableComboBoxModel model = (MutableComboBoxModel) combo.getModel(); if (model.getSize() == 0) { model.insertElementAt(item, 0); return; } Object o = model.getElementAt(0); if (o.equals(item)) { return; } model.removeElement(item); model.insertElementAt(item, 0); combo.setSelectedIndex(0); } /** * Repeat the string source repeat times. * If repeats == 0 then empty String is returned * if source is null, then empty string is returned * @param source * @param repeat * @return source String repeated repeat times. */ public static String repeatString(String source, int repeat) { if (repeat < 0) { throw new IllegalArgumentException("Cannot repeat " + repeat + " times."); } if (repeat == 0 || source == null || source.length() == 0) { return ""; } StringBuffer buffer = new StringBuffer(); for (int i = 0; i < repeat; i++) { buffer.append(source); } return buffer.toString(); } /** * Checks if the given string is null, empty or contains whitespace only * @param string * @return true if string is null, empty or contains whitespace only, false * otherwise. */ public static boolean isEmptyOrBlanks(String string) { if (string == null || string.length() == 0) { return true; } for (int i = 0; i < string.length(); i++) { char c = string.charAt(i); if (!Character.isWhitespace(c)) { return false; } } return true; } /** * Return the TabStop property for the given text component, or 0 if not * used * @param text * @return */ public static int getTabSize(JTextComponent text) { Integer tabs = (Integer) text.getDocument().getProperty(PlainDocument.tabSizeAttribute); return (null == tabs) ? 0 : tabs.intValue(); } /** * Insert the given String into the textcomponent. If the string contains * the | vertical BAr char, then it will not be inserted, and the cursor will * be set to its location. * If there are TWO vertical bars, then the text between them will be selected * FIXME: add following feature * If the String is multi-line, then it will be indented with the same * indentattion as the line with pos. * @param target * @param dot * @param toInsert * @throws javax.swing.text.BadLocationException */ public static void insertMagicString(JTextComponent target, int dot, String toInsert) throws BadLocationException { Document doc = target.getDocument(); if (toInsert.indexOf('|') >= 0) { int ofst = toInsert.indexOf('|'); int ofst2 = toInsert.indexOf('|', ofst + 1); toInsert = toInsert.replace("|", ""); doc.insertString(dot, toInsert, null); dot = target.getCaretPosition(); final int strLength = toInsert.length(); if (ofst2 > 0) { // note that we already removed the first |, so end offset is now // one less than what it was. target.select(dot + ofst - strLength, dot + ofst2 - strLength - 1); } else { target.setCaretPosition(dot + ofst -strLength); } } else { doc.insertString(dot, toInsert, null); } } // This is used internally to avoid NPE if we have no Strings static String[] EMPTY_STRING_ARRAY = new String[0]; // This is used to quickly create Strings of at most 16 spaces (using substring) static String SPACES = " "; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/CaretMonitor.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import javax.swing.JLabel; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.text.BadLocationException; import javax.swing.text.JTextComponent; import jsyntaxpane.SyntaxDocument; /** * This class can be used to display the caret location in friendly manner for * an EditorPane. * * FIXME: Add configurable position text using String.format and arrays of locations * * @author Ayman Al-Sairafi */ public class CaretMonitor implements CaretListener { private JLabel label; private JTextComponent text; public CaretMonitor(JTextComponent text, JLabel label) { this.label = label; this.text = text; text.addCaretListener(this); } public void caretUpdate(CaretEvent evt) { if (text.getDocument() instanceof SyntaxDocument) { try { if (text.getSelectionStart() == text.getSelectionEnd()) { int pos = evt.getDot(); String loc = String.format("%d:%d (%d)", ActionUtils.getLineNumber(text, pos) + 1, ActionUtils.getColumnNumber(text, pos) + 1, pos); label.setText(loc); } else { int start = text.getSelectionStart(); int end = text.getSelectionEnd(); String loc = String.format("%d:%d - %d:%d (%d)", ActionUtils.getLineNumber(text, start) + 1, ActionUtils.getColumnNumber(text, start) + 1, ActionUtils.getLineNumber(text, end) + 1, ActionUtils.getColumnNumber(text, end) + 1, (end - start)); label.setText(loc); } } catch (BadLocationException ex) { label.setText("Ex: " + ex.getMessage()); } } else { label.setText("Position"); } } @Override protected void finalize() throws Throwable { text.removeCaretListener(this); super.finalize(); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ComboCompletionAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.Frame; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.SwingUtilities; import javax.swing.text.BadLocationException; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.Token; import jsyntaxpane.util.Configuration; import jsyntaxpane.util.JarServiceProvider; /** * ComboBox like Completion Action: * This will display a list of items to choose from, its can be used similar to * IntelliSense * * @author Ayman Al-Sairafi */ public class ComboCompletionAction extends TextAction implements SyntaxAction { final private static Set CLOSING = new HashSet() { { add(")"); add("}"); add("["); } }; final private static String MEMBER_SEPARATOR = "."; Map completions; ComboCompletionDialog dlg; private String[] items; public ComboCompletionAction() { super("COMBO_COMPLETION"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null && target.getDocument() instanceof SyntaxDocument) { SyntaxDocument sDoc = (SyntaxDocument) target.getDocument(); int dot = target.getCaretPosition(); Token token = sDoc.getTokenAt(dot); String abbrev = ""; try { if (token != null) { abbrev = token.getText(sDoc); while (CLOSING.contains(abbrev)) { token = sDoc.getTokenAt(token.start - 1); abbrev = token.getText(sDoc); } if (MEMBER_SEPARATOR.equals(abbrev)) { abbrev = "[" + ActionUtils.getTokenStringAt(sDoc, token.start - 1) + "]" + abbrev; } else { Token prev = sDoc.getTokenAt(token.start - 1); if (prev != null && MEMBER_SEPARATOR.equals(prev.getText(sDoc))) { abbrev = "[" + ActionUtils.getTokenStringAt(sDoc, prev.start - 1) + "]" + MEMBER_SEPARATOR + abbrev; } } sDoc.remove(token.start, token.length); dot = token.start; } Frame frame = ActionUtils.getFrameFor(target); if (dlg == null) { dlg = new ComboCompletionDialog(frame, true, items); } dlg.setLocationRelativeTo(frame); Point p = frame.getLocation(); // Get location of Dot in rt Rectangle rt = target.modelToView(dot); Point loc = new Point(rt.x, rt.y); // convert the location from Text Componet coordinates to // Frame coordinates... loc = SwingUtilities.convertPoint(target, loc, frame); // and then to Screen coordinates SwingUtilities.convertPointToScreen(loc, frame); dlg.setLocation(loc); dlg.setFonts(target.getFont()); dlg.setText(abbrev); dlg.setVisible(true); String res = dlg.getResult(); ActionUtils.insertMagicString(target, dot, res); } catch (BadLocationException ex) { Logger.getLogger(ComboCompletionAction.class.getName()).log(Level.SEVERE, null, ex); } } } /** * The completions will for now reside on another properties style file * referenced by prefix.Completions.File * * @param config * @param prefix * @param name */ public void config(Configuration config, String prefix, String name) { // for now we will use just one list for anything. This can be modified // by having a map from TokenType to String[] or something.... items = config.getPrefixPropertyList(prefix, name + ".Items"); } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ComboCompletionDialog.form ================================================
================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ComboCompletionDialog.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.Font; import java.awt.event.KeyEvent; import java.util.Vector; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; /** * * @author Ayman Al-Sairafi */ public class ComboCompletionDialog extends javax.swing.JDialog { /** * The result returned to the caller */ private String result = null; /** * The current filter, to avoid refiltering the items */ public String escapeChars = ";(= \t\n"; public String[] items; /** Creates new form ComboCompletionDialog * @param parent * @param modal * @param items */ public ComboCompletionDialog(java.awt.Frame parent, boolean modal, String[] items) { super(parent, modal); initComponents(); this.items = items; jLstItems.setListData(items); jTxtItem.getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { refilterList(); } public void removeUpdate(DocumentEvent e) { refilterList(); } public void changedUpdate(DocumentEvent e) { refilterList(); } }); // This will allow the textfield to receive TAB keys jTxtItem.setFocusTraversalKeysEnabled(false); } public void setFonts(Font font) { jTxtItem.setFont(font); jLstItems.setFont(font); doLayout(); } public void setText(String abbrev) { jTxtItem.setText(abbrev); } private void refilterList() { String prefix = jTxtItem.getText(); Vector filtered = new Vector(); Object selected = jLstItems.getSelectedValue(); for (String s : items) { if (s.startsWith(prefix)) { filtered.add(trimPrefix(s)); } } jLstItems.setListData(filtered); if (selected != null) { jLstItems.setSelectedValue(selected, true); } else { jLstItems.setSelectedIndex(0); } } private String trimPrefix(String item) { int idx1 = item.indexOf("["); int idx2 = item.indexOf("]"); if (idx1 > -1 && idx2 > -1) { return (idx1 > 0 ? item.substring(0, idx1 - 1) : "") + (idx2 < item.length() - 1 ? item.substring(idx2 + 1) : ""); } return item; } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { jTxtItem = new javax.swing.JTextField(); jScrollPane1 = new javax.swing.JScrollPane(); jLstItems = new javax.swing.JList(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setResizable(false); setUndecorated(true); jTxtItem.setBorder(null); jTxtItem.addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent evt) { jTxtItemKeyPressed(evt); } }); jLstItems.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); jLstItems.setFocusable(false); jScrollPane1.setViewportView(jLstItems); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jTxtItem, javax.swing.GroupLayout.DEFAULT_SIZE, 270, Short.MAX_VALUE) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 270, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jTxtItem, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 111, Short.MAX_VALUE)) ); pack(); }// //GEN-END:initComponents private void jTxtItemKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTxtItemKeyPressed int i = jLstItems.getSelectedIndex(); switch (evt.getKeyCode()) { case KeyEvent.VK_ESCAPE: result = jTxtItem.getText(); setVisible(false); return; case KeyEvent.VK_DOWN: if (i < jLstItems.getModel().getSize() - 1) { i++; } jLstItems.setSelectedIndex(i); jLstItems.ensureIndexIsVisible(i); break; case KeyEvent.VK_UP: if (i > 0) { i--; } jLstItems.setSelectedIndex(i); jLstItems.ensureIndexIsVisible(i); break; } if (escapeChars.indexOf(evt.getKeyChar()) >= 0) { if (jLstItems.getSelectedIndex() >= 0) { result = jLstItems.getSelectedValue().toString(); } else { result = jTxtItem.getText(); } char pressed = evt.getKeyChar(); // we need to just accept ENTER, and replace the tab with a single // space if (pressed != '\n') { result += (pressed == '\t') ? ' ' : pressed; } setVisible(false); } }//GEN-LAST:event_jTxtItemKeyPressed /** * Gets the selected text shown on the dialog. * @return the selected text, or empty string if nothing is selected */ public String getResult() { return result == null ? "" : trimPrefix(result); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JList jLstItems; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTextField jTxtItem; // End of variables declaration//GEN-END:variables } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/DeleteLinesAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.text.BadLocationException; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.util.Configuration; /** * This Action deletes the current line, or all the highlighted lines. * @author Ayman Al-Sairafi */ public class DeleteLinesAction extends TextAction implements SyntaxAction { public DeleteLinesAction() { super("DELETE_LINES"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { try { SyntaxDocument sDoc = (SyntaxDocument) target.getDocument(); int st = sDoc.getLineStartOffset(target.getSelectionStart()); int en = sDoc.getLineEndOffset(target.getSelectionEnd()); sDoc.remove(st, en - st); } catch (BadLocationException ex) { Logger.getLogger(DeleteLinesAction.class.getName()).log(Level.SEVERE, null, ex); } } } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/DuplicateLinesAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.text.BadLocationException; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.util.Configuration; /** * This Action duplicates the current line, or all the highlighted lines. * @author Ayman Al-Sairafi */ public class DuplicateLinesAction extends TextAction implements SyntaxAction { public DuplicateLinesAction() { super("DUPLICATE_LINES"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { try { SyntaxDocument sDoc = (SyntaxDocument) target.getDocument(); int st = sDoc.getLineStartOffset(target.getSelectionStart()); int en = sDoc.getLineEndOffset(target.getSelectionEnd()); String dupLines = sDoc.getText(st, en-st); sDoc.insertString(st, dupLines, null); } catch (BadLocationException ex) { Logger.getLogger(DuplicateLinesAction.class.getName()).log(Level.SEVERE, null, ex); } } } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/FindReplaceActions.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JOptionPane; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.util.Configuration; /** * Finder class. This class contains the general Find, Find Next, * Find Previous, and the Find Marker Actions. * * Note that all Actions are subclasses of this class because all actions * require the find text to be shared among them. This is the best approach * to have all Action classes share this same data. * * @author Ayman Al-Sairafi */ public class FindReplaceActions implements SyntaxAction { private Pattern pattern = null; private boolean wrap = true; private final FindDialogAction findDialogAction = new FindDialogAction(); private final FindNextAction findNextAction = new FindNextAction(); private ReplaceDialog dlg; public FindReplaceActions() { } public TextAction getFindDialogAction() { return findDialogAction; } public TextAction getFindNextAction() { return findNextAction; } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { if(key.equals("FIND") ) { return findDialogAction; } else if(key.equals("REPLACE")) { return findDialogAction; } else if(key.equals("FIND_NEXT")) { return findNextAction; } else { throw new IllegalArgumentException("Bad Action: " + key); } } /** * This class displays the Find Dialog. The dialog will use the pattern * and will update it once it is closed. */ class FindDialogAction extends TextAction { public FindDialogAction() { super("FIND_ACTION"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { showDialog(target); } } } /** * This class performs a Find Next operation by using the current pattern */ class FindNextAction extends TextAction { public FindNextAction() { super("FIND_NEXT"); } public void actionPerformed(ActionEvent e) { // if we did not start searching, return now if (pattern == null) { return; } JTextComponent target = getTextComponent(e); doFindNext(target); } } /** * Display an OptionPane dialog that the search string is not found */ public void msgNotFound() { JOptionPane.showMessageDialog(null, "Search String " + pattern + " not found", "Find", JOptionPane.INFORMATION_MESSAGE); } /** * Show the dialog * @param targetFrame * @param sDoc * @param target */ private void showDialog(JTextComponent target) { if (dlg == null) { dlg = new ReplaceDialog(target, FindReplaceActions.this); } dlg.setVisible(true); } /** * Perform a FindNext operation on the given text component. Position * the caret at the start of the next found pattern * @param target */ public void doFindNext(JTextComponent target) { if (target == null || pattern == null) { return; } SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(target); if (sDoc == null) { return; } int start = target.getCaretPosition() + 1; // we must advance the position by one, otherwise we will find // the same text again if (start >= sDoc.getLength()) { start = 0; } Matcher matcher = sDoc.getMatcher(pattern, start); if (matcher != null && matcher.find()) { // since we used an offset in the matcher, the matcher location // MUST be offset by that location target.select(matcher.start() + start, matcher.end() + start); } else { if (isWrap()) { matcher = sDoc.getMatcher(pattern); if (matcher != null && matcher.find()) { target.select(matcher.start(), matcher.end()); } else { msgNotFound(); } } else { msgNotFound(); } } } /** * Perform a replace all operation on the given component. * Note that this create a new duplicate String big as the entire * document and then assign it to the target text component * @param target * @param replacement */ public void replaceAll(JTextComponent target, String replacement) { SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(target); if (pattern == null || sDoc == null) { return; } Matcher matcher = sDoc.getMatcher(pattern); String newText = matcher.replaceAll(replacement); target.setText(newText); } // - Getters and setters ------------------------------------------------- public Pattern getPattern() { return pattern; } public void setPattern(Pattern pattern) { this.pattern = pattern; } public boolean isWrap() { return wrap; } public void setWrap(boolean wrap) { this.wrap = wrap; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/GotoLineAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import java.util.WeakHashMap; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.util.Configuration; /** * This actions displays the GotoLine dialog */ public class GotoLineAction extends TextAction implements SyntaxAction { private static WeakHashMap DIALOGS = new WeakHashMap(); public GotoLineAction() { super("GOTO_LINE"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); GotoLineDialog dlg = DIALOGS.get(target); if(dlg == null) { dlg = new GotoLineDialog(target); DIALOGS.put(target, dlg); } dlg.setVisible(true); } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/GotoLineDialog.form ================================================
================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/GotoLineDialog.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import javax.swing.JOptionPane; import javax.swing.text.JTextComponent; /** * A simple dialog to prompt for a line number and go to it * @author Ayman Al-Sairafi */ public class GotoLineDialog extends javax.swing.JDialog { private JTextComponent text; /** * Creates new form GotoLineDialog * @param text */ public GotoLineDialog(JTextComponent text) { super(ActionUtils.getFrameFor(text), false); initComponents(); this.text = text; setLocationRelativeTo(text.getRootPane()); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { jCmbLineNumbers = new javax.swing.JComboBox(); jBtnOk = new javax.swing.JButton(); setTitle("Goto Line"); setModal(true); setName(""); // NOI18N setResizable(false); jCmbLineNumbers.setEditable(true); jCmbLineNumbers.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jCmbLineNumbersActionPerformed(evt); } }); jBtnOk.setText("Go"); jBtnOk.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jBtnOkActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jCmbLineNumbers, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jBtnOk, javax.swing.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jCmbLineNumbers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jBtnOk)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); }// //GEN-END:initComponents private void jBtnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnOkActionPerformed setTextPos(); }//GEN-LAST:event_jBtnOkActionPerformed private void setTextPos() { Object line = jCmbLineNumbers.getSelectedItem(); if (line != null) { try { int lineNr = Integer.parseInt(line.toString()); int pos = ActionUtils.getDocumentPosition(text, lineNr, 0); ActionUtils.insertIntoCombo(jCmbLineNumbers, line); text.setCaretPosition(pos); setVisible(false); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(this, "Invalid Number: " + line, "Number Error", JOptionPane.ERROR_MESSAGE); } } } private void jCmbLineNumbersActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCmbLineNumbersActionPerformed // FIXME: this is called twice by the action, skip it setTextPos(); // FIXME: Add ESC key listener to hide the dialog }//GEN-LAST:event_jCmbLineNumbersActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton jBtnOk; private javax.swing.JComboBox jCmbLineNumbers; // End of variables declaration//GEN-END:variables } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/IndentAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import javax.swing.text.DefaultEditorKit; import javax.swing.text.JTextComponent; import javax.swing.text.PlainDocument; import javax.swing.text.TextAction; import jsyntaxpane.util.Configuration; /** * IndentAction is used to replace Tabs with spaces. If there is selected * text, then the lines spanning the selection will be shifted * right by one tab-width space character */ public class IndentAction extends DefaultEditorKit.InsertTabAction implements SyntaxAction { public IndentAction() { super(); } @Override public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { String selected = target.getSelectedText(); if (selected == null) { PlainDocument pDoc = (PlainDocument) target.getDocument(); Integer tabStop = (Integer) pDoc.getProperty(PlainDocument.tabSizeAttribute); int lineStart = pDoc.getParagraphElement(target.getCaretPosition()).getStartOffset(); int column = target.getCaretPosition() - lineStart; int needed = tabStop - (column % tabStop); target.replaceSelection(ActionUtils.SPACES.substring(0, needed)); } else { String[] lines = ActionUtils.getSelectedLines(target); int start = target.getSelectionStart(); StringBuilder sb = new StringBuilder(); for (String line : lines) { sb.append('\t'); sb.append(line); sb.append('\n'); } target.replaceSelection(sb.toString()); target.select(start, start + sb.length()); } } } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/JIndentAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.util.Configuration; public class JIndentAction extends TextAction implements SyntaxAction { /** * creates new JIndentAction. * Initial Code contributed by ser... AT mail.ru */ public JIndentAction() { super("JINDENT"); } /** * {@inheritDoc} * @param e */ @Override public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(target); int pos = target.getCaretPosition(); int start = sDoc.getParagraphElement(pos).getStartOffset(); String line = ActionUtils.getLine(target); String lineToPos = line.substring(0, pos - start); String prefix = ActionUtils.getIndent(line); int tabSize = ActionUtils.getTabSize(target); if (lineToPos.trim().endsWith("{")) { prefix += ActionUtils.SPACES.substring(0, tabSize); } else { String noComment = sDoc.getUncommentedText(start, pos); // skip EOL comments if (noComment.trim().endsWith("{")) { prefix += ActionUtils.SPACES.substring(0, tabSize); } } target.replaceSelection("\n" + prefix); } } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/JUnindentAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import javax.swing.text.BadLocationException; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.Token; import jsyntaxpane.util.Configuration; public class JUnindentAction extends TextAction implements SyntaxAction { /** * creates new JUnindentAction. * Initial Code contributed by ser... AT mail.ru */ public JUnindentAction() { super("JUNINDENT"); } /** * {@inheritDoc} */ @Override public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(target); int pos = target.getCaretPosition(); int start = sDoc.getParagraphElement(pos).getStartOffset(); String line = ActionUtils.getLine(target); if (ActionUtils.isEmptyOrBlanks(line)) { try { sDoc.insertString(pos, "}", null); Token t = sDoc.getPairFor(sDoc.getTokenAt(pos)); if (null != t) { String pairLine = ActionUtils.getLineAt(target, t.start); String indent = ActionUtils.getIndent(pairLine); sDoc.replace(start, line.length() + 1, indent + "}", null); } } catch (BadLocationException ble) { target.replaceSelection("}"); } } else { target.replaceSelection("}"); } } } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/JavaIndentAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.text.BadLocationException; import javax.swing.text.JTextComponent; import javax.swing.text.PlainDocument; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.util.Configuration; /** * This action performs Java Indentation each time VK_ENTER is pressed * Java Indentation is inserting the same amount of spaces as * the line above. * If the current line ends with a '{' character, then an additional virtual * tab is inserted. * If the trimmed current line ends with '}', then the line is unindented */ public class JavaIndentAction extends TextAction implements SyntaxAction { public JavaIndentAction() { super("JAVA_INDENT"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { String line = ActionUtils.getLine(target); String prefix = ActionUtils.getIndent(line); Integer tabSize = (Integer) target.getDocument().getProperty(PlainDocument.tabSizeAttribute); if (line.trim().endsWith("{")) { prefix += ActionUtils.SPACES.substring(0, tabSize); } SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(target); if (sDoc != null && line.trim().equals("}")) { int pos = target.getCaretPosition(); int start = sDoc.getParagraphElement(pos).getStartOffset(); int end = sDoc.getParagraphElement(pos).getEndOffset(); if (end >= sDoc.getLength()) { end--; } if (line.startsWith(ActionUtils.SPACES.substring(0, tabSize))) { try { sDoc.replace(start, end - start, line.substring(tabSize) + "\n", null); } catch (BadLocationException ex) { Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); } } else { target.replaceSelection("\n" + prefix); } } else { target.replaceSelection("\n" + prefix); } } } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/MapCompletionAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import java.util.Map; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.Token; import jsyntaxpane.util.Configuration; import jsyntaxpane.util.JarServiceProvider; /** * Completion Actions: * All completions are based on a simple String to String Map. */ public class MapCompletionAction extends TextAction implements SyntaxAction { Map completions; public MapCompletionAction() { super("MAP_COMPLETION"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null && target.getDocument() instanceof SyntaxDocument) { SyntaxDocument sDoc = (SyntaxDocument) target.getDocument(); int dot = target.getCaretPosition(); Token token = sDoc.getTokenAt(dot); if (token != null) { String abbriv = ActionUtils.getTokenStringAt(sDoc, dot); if (completions.containsKey(abbriv)) { String completed = completions.get(abbriv); if (completed.indexOf('|') >= 0) { int ofst = completed.length() - completed.indexOf('|') - 1; sDoc.replaceToken(token, completed.replace("|", "")); target.setCaretPosition(target.getCaretPosition() - ofst); } else { sDoc.replaceToken(token, completed); } } } } } /** * The completions will for now reside on another properties style file * referenced by prefix.Completions.File * * @param config * @param prefix * @param name */ public void config(Configuration config, String prefix, String name) { String completionsFile = config.getPrefixProperty(prefix, "Completions.File", "NONE"); if(completionsFile != null) { completions = JarServiceProvider.readStringsMap(completionsFile); } } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/PairAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import java.util.HashMap; import java.util.Map; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.util.Configuration; /** * A Pair action inserts a pair of characters (left and right) around the * current selection, and then places the caret between them * * The pairs are hard-coded here. */ public class PairAction extends TextAction implements SyntaxAction { public PairAction() { super("PAIR_ACTION"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { String left = e.getActionCommand(); String right = PAIRS.get(left); String selected = target.getSelectedText(); if (selected != null) { target.replaceSelection(left + selected + right); } else { target.replaceSelection(left + right); } target.setCaretPosition(target.getCaretPosition() - 1); } } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } private static Map PAIRS = new HashMap(4); static { PAIRS.put("(", ")"); PAIRS.put("[", "]"); PAIRS.put("\"", "\""); PAIRS.put("'", "'"); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/RedoAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.util.Configuration; /** * Redo action */ public class RedoAction extends TextAction implements SyntaxAction { public RedoAction() { super("REDO"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { if (target.getDocument() instanceof SyntaxDocument) { SyntaxDocument sDoc = (SyntaxDocument) target.getDocument(); sDoc.doRedo(); } } } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ReplaceDialog.form ================================================
================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ReplaceDialog.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ContainerEvent; import java.awt.event.KeyEvent; import jsyntaxpane.components.Markers; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.HeadlessException; import java.awt.event.ContainerListener; import java.awt.event.KeyListener; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.swing.JOptionPane; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.text.JTextComponent; /** * A Find and Replace Dialog. The dialog will also act as a listener to * Document changes so that all highlights are updated if the document is * changed. * * @author Ayman Al-Sairafi */ public class ReplaceDialog extends javax.swing.JDialog implements CaretListener, KeyListener, ContainerListener { private JTextComponent textComponent; private FindReplaceActions finder; private static Markers.SimpleMarker SEARCH_MARKER = new Markers.SimpleMarker(Color.YELLOW); /** Creates new form FindDialog */ public ReplaceDialog(JTextComponent text, FindReplaceActions finderActions) { super(ActionUtils.getFrameFor(text), false); initComponents(); registerKeyAction(this); textComponent = text; finder = finderActions; textComponent.addCaretListener(this); setLocationRelativeTo(text.getRootPane()); } /** * updates the highlights in the document when it is updated. * This is called by the DocumentListener methods */ public void updateHighlights() { Markers.removeMarkers(textComponent, SEARCH_MARKER); if (jTglHighlight.isSelected()) { Markers.markAll(textComponent, finder.getPattern(), SEARCH_MARKER); } } private void showRegexpError(PatternSyntaxException ex) throws HeadlessException { JOptionPane.showMessageDialog(this, "Regexp error: " + ex.getMessage(), "Regular Expression Error", JOptionPane.ERROR_MESSAGE); jCmbFind.requestFocus(); } /** * update the finder object with data from our UI */ private void updateFinder() { int flag = 0; if (!jChkRegex.isSelected()) { flag |= Pattern.LITERAL; } flag |= (jChkIgnoreCase.isSelected()) ? Pattern.CASE_INSENSITIVE : 0; if (jChkIgnoreCase.isSelected()) { flag |= Pattern.CASE_INSENSITIVE; } String regex = (String) jCmbFind.getSelectedItem(); if (regex != null && regex.length() > 0) { Pattern pattern = Pattern.compile(regex, flag); finder.setWrap(jChkWrap.isSelected()); finder.setPattern(pattern); ActionUtils.insertIntoCombo(jCmbFind, regex); } else { finder.setPattern(null); } } /** * This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { jLabel1 = new javax.swing.JLabel(); jBtnNext = new javax.swing.JButton(); jLblStatus = new javax.swing.JLabel(); jBtnReplaceAll = new javax.swing.JButton(); jChkWrap = new javax.swing.JCheckBox(); jChkRegex = new javax.swing.JCheckBox(); jChkIgnoreCase = new javax.swing.JCheckBox(); jLabel2 = new javax.swing.JLabel(); jTglHighlight = new javax.swing.JToggleButton(); jCmbReplace = new javax.swing.JComboBox(); jCmbFind = new javax.swing.JComboBox(); setTitle("Find and Replace"); setName(""); // NOI18N setResizable(false); jLabel1.setText("Find"); jBtnNext.setMnemonic('N'); jBtnNext.setText("Next"); jBtnNext.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jBtnNextActionPerformed(evt); } }); jBtnReplaceAll.setMnemonic('H'); jBtnReplaceAll.setText("Replace All"); jBtnReplaceAll.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jBtnReplaceAllActionPerformed(evt); } }); jChkWrap.setMnemonic('W'); jChkWrap.setText("Wrap around"); jChkWrap.setToolTipText("Wrap to beginning when end is reached"); jChkRegex.setMnemonic('R'); jChkRegex.setText("Regular Expression"); jChkIgnoreCase.setMnemonic('I'); jChkIgnoreCase.setText("Ignore Case"); jLabel2.setText("Replace"); jTglHighlight.setText("Highlight"); jTglHighlight.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jTglHighlightActionPerformed(evt); } }); jCmbReplace.setEditable(true); jCmbFind.setEditable(true); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jLabel2) .addComponent(jLabel1)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jChkRegex) .addComponent(jChkIgnoreCase)) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(178, 178, 178) .addComponent(jLblStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 39, Short.MAX_VALUE) .addGap(3, 3, 3)) .addGroup(layout.createSequentialGroup() .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jChkWrap, javax.swing.GroupLayout.PREFERRED_SIZE, 105, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addComponent(jCmbFind, 0, 337, Short.MAX_VALUE) .addComponent(jCmbReplace, 0, 337, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jBtnReplaceAll, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 102, Short.MAX_VALUE) .addComponent(jBtnNext, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 102, Short.MAX_VALUE) .addComponent(jTglHighlight, javax.swing.GroupLayout.DEFAULT_SIZE, 102, Short.MAX_VALUE)) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(29, 29, 29) .addComponent(jLblStatus)) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(jCmbFind, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jBtnNext)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(jBtnReplaceAll) .addComponent(jCmbReplace, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jChkRegex) .addComponent(jChkWrap, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jTglHighlight)))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jChkIgnoreCase) .addContainerGap()) ); pack(); }// //GEN-END:initComponents private void jBtnNextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnNextActionPerformed try { updateFinder(); finder.doFindNext(textComponent); textComponent.requestFocusInWindow(); } catch (PatternSyntaxException ex) { showRegexpError(ex); } }//GEN-LAST:event_jBtnNextActionPerformed private void jBtnReplaceAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnReplaceAllActionPerformed try { updateFinder(); String replacement = (String) jCmbReplace.getSelectedItem(); ActionUtils.insertIntoCombo(jCmbFind, replacement); finder.replaceAll(textComponent, replacement); textComponent.requestFocusInWindow(); } catch (PatternSyntaxException ex) { showRegexpError(ex); } }//GEN-LAST:event_jBtnReplaceAllActionPerformed private void jTglHighlightActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTglHighlightActionPerformed updateFinder(); updateHighlights(); }//GEN-LAST:event_jTglHighlightActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton jBtnNext; private javax.swing.JButton jBtnReplaceAll; private javax.swing.JCheckBox jChkIgnoreCase; private javax.swing.JCheckBox jChkRegex; private javax.swing.JCheckBox jChkWrap; private javax.swing.JComboBox jCmbFind; private javax.swing.JComboBox jCmbReplace; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLblStatus; private javax.swing.JToggleButton jTglHighlight; // End of variables declaration//GEN-END:variables public void caretUpdate(CaretEvent e) { updateHighlights(); } public void keyTyped(KeyEvent arg0) { } public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { this.setVisible(false); } } public void keyReleased(KeyEvent arg0) { } public void componentAdded(ContainerEvent e) { registerKeyAction(e.getChild()); } public void componentRemoved(ContainerEvent e) { registerKeyAction(e.getChild()); } private void registerKeyAction(Component c) { if (c instanceof ReplaceDialog == false) { c.removeKeyListener(this); c.addKeyListener(this); } if (c instanceof Container) { Container cnt = (Container) c; cnt.removeContainerListener(this); cnt.addContainerListener(this); Component[] ch = cnt.getComponents(); for (int i = 0; i < ch.length; i++) { registerKeyAction(ch[i]); } } } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/SmartIndent.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; /** * This action performs SmartIndentation each time VK_ENTER is pressed * SmartIndentation is inserting the same amount of spaces as * the line above. May not be too smart, but good enough. */ public class SmartIndent extends TextAction { public SmartIndent() { super("SMART_INDENT"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { String line = ActionUtils.getLine(target); target.replaceSelection("\n" + ActionUtils.getIndent(line)); } } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/SyntaxAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import javax.swing.text.TextAction; import jsyntaxpane.util.Configuration; /** * All JSyntaxPane Keyboard related actions implement this class. These * classes are created dynamically, and then registered to the SyntaxKit. * * A class may have multiple TextActions that may be related. Each EditorKit * that is installed will have only one instance of each class, even if more * than one action is specified. * * The key value pairs in the COnfiguration are of the form: * * [EditorKit.]Action.NAME = class, keyboard key * * @author Ayman Al-Sairafi */ public interface SyntaxAction { /** * Configure the actions in this class * @param config * @param prefix * @param name: name of the action, will be obtained from the property Key * as the text following the Action. */ public void config(Configuration config, String prefix, String name); /** * A class may contain several related actions, this will return the action * with given name. * @param name * @return */ public TextAction getAction(String name); } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ToggleCommentsAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.security.KeyStore; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.util.Configuration; /** * This action will toggle comments on or off on selected whole lines. * * @author Ayman Al-Sairafi */ public class ToggleCommentsAction extends TextAction implements SyntaxAction { protected String lineCommentStart = "// "; protected Pattern lineCommentPattern = null; /** * creates new JIndentAction. * Initial Code contributed by ser... AT mail.ru */ public ToggleCommentsAction() { super("TOGGLE"); } /** * {@inheritDoc} * @param e */ @Override public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null && target.getDocument() instanceof SyntaxDocument) { String[] lines = ActionUtils.getSelectedLines(target); StringBuffer toggled = new StringBuffer(); for (int i = 0; i < lines.length; i++) { Matcher m = lineCommentPattern.matcher(lines[i]); if (m.find()) { toggled.append(m.replaceFirst("$2")); } else { toggled.append(lineCommentStart); toggled.append(lines[i]); } toggled.append('\n'); } target.replaceSelection(toggled.toString()); } } public void config(Configuration config, String prefix, String name) { // we need to escape the chars lineCommentStart = config.getPrefixProperty(prefix, name + ".LineComments", "// ").replace("\"", ""); lineCommentPattern = Pattern.compile("(^" + lineCommentStart + ")(.*)"); } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/UndoAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import javax.swing.text.JTextComponent; import javax.swing.text.TextAction; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.util.Configuration; /** * Undo action */ public class UndoAction extends TextAction implements SyntaxAction { public UndoAction() { super("UNDO"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); if (target != null) { if (target.getDocument() instanceof SyntaxDocument) { SyntaxDocument sDoc = (SyntaxDocument) target.getDocument(); sDoc.doUndo(); } } } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/UnindentAction.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.actions; import java.awt.event.ActionEvent; import javax.swing.text.JTextComponent; import javax.swing.text.PlainDocument; import javax.swing.text.TextAction; import jsyntaxpane.util.Configuration; /** * This is usually mapped to Shift-TAB to unindent the selection. The * current line, or the selected lines are un-indented by the tabstop of the * document. */ public class UnindentAction extends TextAction implements SyntaxAction { public UnindentAction() { super("UNINDENT"); } public void actionPerformed(ActionEvent e) { JTextComponent target = getTextComponent(e); Integer tabStop = (Integer) target.getDocument().getProperty(PlainDocument.tabSizeAttribute); String indent = ActionUtils.SPACES.substring(0, tabStop); if (target != null) { String[] lines = ActionUtils.getSelectedLines(target); int start = target.getSelectionStart(); StringBuilder sb = new StringBuilder(); for (String line : lines) { if (line.startsWith(indent)) { sb.append(line.substring(indent.length())); } else if (line.startsWith("\t")) { sb.append(line.substring(1)); } else { sb.append(line); } sb.append('\n'); } target.replaceSelection(sb.toString()); target.select(start, start + sb.length()); } } public void config(Configuration config, String prefix, String name) { } public TextAction getAction(String key) { return this; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/components/LineNumbersRuler.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.components; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.logging.Logger; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.JTextComponent; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.actions.GotoLineDialog; import jsyntaxpane.actions.ActionUtils; import jsyntaxpane.util.Configuration; /** * LineRuleis used to number the lines in the EdiorPane * @author Ayman Al-Sairafi */ public class LineNumbersRuler extends JComponent implements SyntaxComponent, PropertyChangeListener, DocumentListener { public static final String PROPERTY_BACKGROUND = "LineNumbers.Background"; public static final String PROPERTY_FOREGROUND = "LineNumbers.Foreground"; public static final String PROPERTY_LEFT_MARGIN = "LineNumbers.LeftMargin"; public static final String PROPERTY_RIGHT_MARGIN = "LineNumbers.RightMargin"; public static final int DEFAULT_R_MARGIN = 5; public static final int DEFAULT_L_MARGIN = 5; private JEditorPane pane; private String format; private int lineCount = -1; private int r_margin; private int l_margin; private int charHeight; private int charWidth; private GotoLineDialog gotoLineDialog = null; private MouseListener mouseListener = null; /** * The status is used to have proper propertyCHange support. We need to know if we are INSTALLING * the component or DE-INSTALLING it */ static enum Status { INSTALLING, DEINSTALLING } private Status status; public LineNumbersRuler() { super(); } @Override protected void paintComponent(Graphics g) { g.setFont(pane.getFont()); Rectangle clip = g.getClipBounds(); g.setColor(getBackground()); g.fillRect(clip.x, clip.y, clip.width, clip.height); g.setColor(getForeground()); int lh = charHeight; int end = clip.y + clip.height + lh; int lineNum = clip.y / lh + 1; // round the start to a multiple of lh, and shift by 2 pixels to align // properly to the text. for (int y = (clip.y / lh) * lh + lh - 2; y <= end; y += lh) { String text = String.format(format, lineNum); g.drawString(text, l_margin, y); lineNum++; if (lineNum > lineCount) { break; } } } /** * Update the size of the line numbers based on the length of the document */ private void updateSize() { int newLineCount = ActionUtils.getLineCount(pane); if (newLineCount == lineCount) { return; } lineCount = newLineCount; int h = lineCount * charHeight + pane.getHeight(); int d = (int) Math.log10(lineCount) + 1; if (d < 1) { d = 1; } int w = d * charWidth + r_margin + l_margin; format = "%" + d + "d"; setPreferredSize(new Dimension(w, h)); if(getParent() != null){ getParent().doLayout(); } } /** * Get the JscrollPane that contains this EditorPane, or null if no * JScrollPane is the parent of this editor * @param editorPane * @return */ public JScrollPane getScrollPane(JTextComponent editorPane) { Container p = editorPane.getParent(); while (p != null) { if (p instanceof JScrollPane) { return (JScrollPane) p; } p = p.getParent(); } return null; } public void config(Configuration config, String prefix) { r_margin = config.getPrefixInteger(prefix, PROPERTY_RIGHT_MARGIN, DEFAULT_R_MARGIN); l_margin = config.getPrefixInteger(prefix, PROPERTY_LEFT_MARGIN, DEFAULT_L_MARGIN); Color foreground = config.getPrefixColor(prefix, PROPERTY_FOREGROUND, Color.BLACK); setForeground(foreground); Color back = config.getPrefixColor(prefix, PROPERTY_BACKGROUND, Color.WHITE); setBackground(back); } public void install(JEditorPane editor) { this.pane = editor; charHeight = pane.getFontMetrics(pane.getFont()).getHeight(); charWidth = pane.getFontMetrics(pane.getFont()).charWidth('0'); editor.addPropertyChangeListener(this); JScrollPane sp = getScrollPane(pane); if (sp == null) { Logger.getLogger(this.getClass().getName()).warning( "JEditorPane is not enclosed in JScrollPane, " + "no LineNumbers will be displayed"); } else { sp.setRowHeaderView(this); this.pane.getDocument().addDocumentListener(this); updateSize(); gotoLineDialog = new GotoLineDialog(pane); mouseListener = new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { gotoLineDialog.setVisible(true); } }; addMouseListener(mouseListener); } status = Status.INSTALLING; } public void deinstall(JEditorPane editor) { removeMouseListener(mouseListener); status = Status.DEINSTALLING; JScrollPane sp = getScrollPane(editor); if (sp != null) { editor.getDocument().removeDocumentListener(this); sp.setRowHeaderView(null); } } public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("document")) { if (evt.getOldValue() instanceof SyntaxDocument) { SyntaxDocument syntaxDocument = (SyntaxDocument) evt.getOldValue(); syntaxDocument.removeDocumentListener(this); } if (evt.getNewValue() instanceof SyntaxDocument && status.equals(Status.INSTALLING)) { SyntaxDocument syntaxDocument = (SyntaxDocument) evt.getNewValue(); syntaxDocument.addDocumentListener(this); } } else if (evt.getPropertyName().equals("font")) { charHeight = pane.getFontMetrics(pane.getFont()).getHeight(); charWidth = pane.getFontMetrics(pane.getFont()).charWidth('0'); } } public void insertUpdate(DocumentEvent e) { updateSize(); } public void removeUpdate(DocumentEvent e) { updateSize(); } public void changedUpdate(DocumentEvent e) { updateSize(); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/components/Markers.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.components; import jsyntaxpane.actions.*; import java.awt.Color; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultHighlighter; import javax.swing.text.Highlighter; import javax.swing.text.JTextComponent; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.Token; /** * This class contains static utility methods to make highliting in text * components easier. * * @author Ayman Al-Sairafi */ public class Markers { // This subclass is used in our highlighting code public static class SimpleMarker extends DefaultHighlighter.DefaultHighlightPainter { public SimpleMarker(Color color) { super(color); } } /** * Removes only our private highlights * This is public so that we can remove the highlights when the editorKit * is unregistered. SimpleMarker can be null, in which case all instances of * our Markers are removed. * @param component the text component whose markers are to be removed * @param marker the SimpleMarker to remove */ public static void removeMarkers(JTextComponent component, SimpleMarker marker) { Highlighter hilite = component.getHighlighter(); Highlighter.Highlight[] hilites = hilite.getHighlights(); for (int i = 0; i < hilites.length; i++) { if (hilites[i].getPainter() instanceof SimpleMarker) { SimpleMarker hMarker = (SimpleMarker) hilites[i].getPainter(); if (marker == null || hMarker.equals(marker)) { hilite.removeHighlight(hilites[i]); } } } } /** * Remove all the markers from an JEditorPane * @param editorPane */ public static void removeMarkers(JTextComponent editorPane) { removeMarkers(editorPane, null); } /** * add highlights for the given Token on the given pane * @param pane * @param token * @param marker */ public static void markToken(JTextComponent pane, Token token, SimpleMarker marker) { markText(pane, token.start, token.end(), marker); } /** * add highlights for the given region on the given pane * @param pane * @param start * @param end * @param marker */ public static void markText(JTextComponent pane, int start, int end, SimpleMarker marker) { try { Highlighter hiliter = pane.getHighlighter(); int selStart = pane.getSelectionStart(); int selEnd = pane.getSelectionEnd(); // if there is no selection or selection does not overlap if(selStart == selEnd || end < selStart || start > selStart) { hiliter.addHighlight(start, end, marker); return; } // selection starts within the highlight, highlight before slection if(selStart > start && selStart < end ) { hiliter.addHighlight(start, selStart, marker); } // selection ends within the highlight, highlight remaining if(selEnd > start && selEnd < end ) { hiliter.addHighlight(selEnd, end, marker); } } catch (BadLocationException ex) { // nothing we can do if the request is out of bound LOG.log(Level.SEVERE, null, ex); } } /** * Mark all text in the document that matches the given pattern * @param pane control to use * @param pattern pattern to match * @param marker marker to use for highlighting */ public static void markAll(JTextComponent pane, Pattern pattern, SimpleMarker marker) { SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(pane); if(sDoc == null || pattern == null) { return; } Matcher matcher = sDoc.getMatcher(pattern); while(matcher.find()) { markText(pane, matcher.start(), matcher.end(), marker); } } private static final Logger LOG = Logger.getLogger(Markers.class.getName()); } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/components/PairsMarker.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.components; import java.awt.Color; import jsyntaxpane.actions.*; import javax.swing.JEditorPane; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.text.JTextComponent; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.Token; import jsyntaxpane.util.Configuration; /** * This class highlights any pairs of the given language. Pairs are defined * with the Token.pairValue. * * @author Ayman Al-Sairafi */ public class PairsMarker implements CaretListener, SyntaxComponent { public static final String PROPERTY_COLOR = "PairMarker.Color"; private JTextComponent pane; private Markers.SimpleMarker marker; public PairsMarker() { } @Override public void caretUpdate(CaretEvent e) { removeMarkers(); int pos = e.getDot(); SyntaxDocument doc = ActionUtils.getSyntaxDocument(pane); Token token = doc.getTokenAt(pos); if (token != null && token.pairValue != 0) { Markers.markToken(pane, token, marker); Token other = doc.getPairFor(token); if (other != null) { Markers.markToken(pane, other, marker); } } } /** * Remove all the highlights from the editor pane. This should be called * when the editorkit is removed. */ public void removeMarkers() { Markers.removeMarkers(pane, marker); } public void config(Configuration config, String prefix) { Color markerColor = new Color(config.getPrefixInteger(prefix, PROPERTY_COLOR, 0xeeee33)); this.marker = new Markers.SimpleMarker(markerColor); } public void install(JEditorPane editor) { pane = editor; pane.addCaretListener(this); } public void deinstall(JEditorPane editor) { pane.removeCaretListener(this); removeMarkers(); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/components/SyntaxComponent.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.components; import javax.swing.JEditorPane; import jsyntaxpane.util.Configuration; /** * A Component that is installed to the EditorKit to perform GUI operations * on the Editor. * * @author Ayman Al-Sairafi */ public interface SyntaxComponent { /** * Configure the component using the given properties. The keys * needed for configuration will be prefixed by the given prefix * @param config configuration data * @param prefix prefix for keys */ public void config(Configuration config, String prefix); /** * Called to install the component on an editor * @param editor */ public void install(JEditorPane editor); /** * Called when the component is to be removed from the editor * @param editor */ public void deinstall(JEditorPane editor); } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/components/TokenMarker.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.components; import jsyntaxpane.actions.*; import java.awt.Color; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.logging.Logger; import javax.swing.JEditorPane; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.Token; import jsyntaxpane.TokenType; import jsyntaxpane.util.Configuration; /** * This class highlights Tokens within a document whenever the caret is moved * to a TokenType provided in the config file. * * @author Ayman Al-Sairafi */ public class TokenMarker implements SyntaxComponent, CaretListener { public static final String DEFAULT_TOKENTYPES = "IDENTIFIER, TYPE, TYPE2, TYPE3"; public static final String PROPERTY_COLOR = "TokenMarker.Color"; public static final String PROPERTY_TOKENTYPES = "TokenMarker.TokenTypes"; private static final int DEFAULT_COLOR = 16772710; private JEditorPane pane; private Set tokenTypes = new HashSet(); private Markers.SimpleMarker marker; /** * Constructs a new Token highlighter */ public TokenMarker() { } @Override public void caretUpdate(CaretEvent e) { int pos = e.getDot(); SyntaxDocument doc = ActionUtils.getSyntaxDocument(pane); Token token = doc.getTokenAt(pos); removeMarkers(); if (token != null && tokenTypes.contains(token.type)) { addMarkers(token); } } /** * removes all markers from the pane. */ public void removeMarkers() { Markers.removeMarkers(pane, marker); } /** * add highlights for the given pattern * @param pattern */ void addMarkers(Token tok) { SyntaxDocument sDoc = (SyntaxDocument) pane.getDocument(); sDoc.readLock(); String text = tok.getText(sDoc); Iterator it = sDoc.getTokens(0, sDoc.getLength()); while (it.hasNext()) { Token nextToken = it.next(); if (nextToken.length == tok.length && text.equals(nextToken.getText(sDoc))) { Markers.markToken(pane, nextToken, marker); } } sDoc.readUnlock(); } @Override public void config(Configuration config, String prefix) { Color markerColor = new Color(config.getPrefixInteger(prefix, PROPERTY_COLOR, DEFAULT_COLOR)); this.marker = new Markers.SimpleMarker(markerColor); String types = config.getPrefixProperty(prefix, PROPERTY_TOKENTYPES, DEFAULT_TOKENTYPES); for (String type : types.split("\\s*,\\s*")) { try { TokenType tt = TokenType.valueOf(type); tokenTypes.add(tt); } catch (IllegalArgumentException e) { LOG.warning("Error in setting up TokenMarker for " + prefix + " - Invalid TokenType: " + type); } } } @Override public void install(JEditorPane editor) { this.pane = editor; pane.addCaretListener(this); } @Override public void deinstall(JEditorPane editor) { removeMarkers(); pane.removeCaretListener(this); } private static final Logger LOG = Logger.getLogger(TokenMarker.class.getName()); } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/BashSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.lexers.BashLexer; /** * * @author Ayman Al-Sairafi */ public class BashSyntaxKit extends DefaultSyntaxKit { public BashSyntaxKit() { super(new BashLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/CSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.Lexer; import jsyntaxpane.lexers.CLexer; /** * * @author Ayman Al-Sairafi */ public class CSyntaxKit extends DefaultSyntaxKit { public CSyntaxKit() { super(new CLexer()); } /** * Construct a JavaSyntaxKit user the supplied lexer. This is protected so * only subclasses may extend this with a new lexer. * @param lexer */ CSyntaxKit(Lexer lexer) { super(lexer); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/ClojureSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.Lexer; import jsyntaxpane.lexers.ClojureLexer; /** * * @author Ayman Al-Sairafi */ public class ClojureSyntaxKit extends DefaultSyntaxKit { public ClojureSyntaxKit() { super(new ClojureLexer()); } public ClojureSyntaxKit(Lexer lexer) { super(lexer); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/CppSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.lexers.CppLexer; /** * * @author Ayman Al-Sairafi */ public class CppSyntaxKit extends CSyntaxKit { public CppSyntaxKit() { super(new CppLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/DOSBatchSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.lexers.DOSBatchLexer; /** * * @author Ayman Al-Sairafi */ public class DOSBatchSyntaxKit extends DefaultSyntaxKit { public DOSBatchSyntaxKit() { super(new DOSBatchLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/GroovySyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.lexers.GroovyLexer; /** * * @author Ayman Al-Sairafi */ public class GroovySyntaxKit extends JavaSyntaxKit { public GroovySyntaxKit() { super(new GroovyLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/JFlexSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.lexers.JFlexLexer; /** * JFlex lexer * @author Ayman Al-Sairafi */ public class JFlexSyntaxKit extends JavaSyntaxKit { public JFlexSyntaxKit() { super(new JFlexLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/JavaScriptSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.lexers.JavaScriptLexer; /** * * @author Ayman Al-Sairafi */ public class JavaScriptSyntaxKit extends DefaultSyntaxKit { public JavaScriptSyntaxKit() { super(new JavaScriptLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/JavaSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.Lexer; import jsyntaxpane.lexers.JavaLexer; /** * * @author Ayman Al-Sairafi */ public class JavaSyntaxKit extends DefaultSyntaxKit { public JavaSyntaxKit() { super(new JavaLexer()); } JavaSyntaxKit(Lexer lexer) { super(lexer); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/PropertiesSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.lexers.PropertiesLexer; /** * * @author Ayman Al-Sairafi */ public class PropertiesSyntaxKit extends DefaultSyntaxKit { public PropertiesSyntaxKit() { super(new PropertiesLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/PythonSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.lexers.PythonLexer; /** * * @author Ayman Al-Sairafi */ public class PythonSyntaxKit extends DefaultSyntaxKit { public PythonSyntaxKit() { super(new PythonLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/RubySyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.lexers.RubyLexer; /** * * @author Ayman Al-Sairafi */ public class RubySyntaxKit extends DefaultSyntaxKit { public RubySyntaxKit() { super(new RubyLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/ScalaSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.Lexer; import jsyntaxpane.lexers.ScalaLexer; /** * * @author Ayman Al-Sairafi */ public class ScalaSyntaxKit extends DefaultSyntaxKit { public ScalaSyntaxKit() { super(new ScalaLexer()); } public ScalaSyntaxKit(Lexer lexer) { super(lexer); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/SqlSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.lexers.SqlLexer; /** * * @author Ayman Al-Sairafi */ public class SqlSyntaxKit extends DefaultSyntaxKit { public SqlSyntaxKit() { super(new SqlLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/TALSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.lexers.TALLexer; /** * * @author Ayman Al-Sairafi */ public class TALSyntaxKit extends DefaultSyntaxKit { public TALSyntaxKit() { super(new TALLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/XmlSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.syntaxkits; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.lexers.XmlLexer; /** * * @author Ayman Al-Sairafi */ public class XmlSyntaxKit extends DefaultSyntaxKit { public XmlSyntaxKit() { super(new XmlLexer()); } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/util/Configuration.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.util; import java.awt.Color; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; /** * Wrapper around the Properties class with more functionality * This is mainly needed to provide easier support for getting values by an * optional prefix. * * @author Ayman Al-Sairafi */ public class Configuration extends Properties { final private Map valueSeparatorMap = new HashMap(); public Configuration(Properties defaults) { super(defaults); } private Configuration() { super(); } /** * Gets the String value for the key prefix.key, or key, or default * @param prefix * @param key * @param Default * @return */ public String getPrefixProperty(String prefix, String key, String Default) { String v = super.getProperty(prefix + "." + key); if (v != null) { return v; } return super.getProperty(key, Default); } /** * Gets a prefixed integer from the properties. If number cannot be found * or if it cannot be decoded, the default is returned * The integer is decoded using {@link Integer.decode(String)} * @param prefix * @param key * @param Default * @return */ public int getPrefixInteger(String prefix, String key, int Default) { String v = getPrefixProperty(prefix, key, null); if (v == null) { return Default; } try { int i = Integer.decode(v); return i; } catch (NumberFormatException e) { LOG.log(Level.WARNING, null, e); return Default; } } /** * Returns a String[] of the comma separated items in the value for * prefix.key or key * Does NOT return null. If the prefix.key or key value is not found, * then an empty string array is returned. So the return of this method * can be used directly in a foreach loop * @param prefix * @param key * @return non-null String[] */ public String[] getPrefixPropertyList(String prefix, String key) { String v = getProperty(prefix + "." + key); if (v == null) { v = getProperty(key); } if (v == null) { return EMPTY_LIST; } return getValueSeparator(prefix).split(v); } /** * Returns a boolean from the configuration * @param prefix * @param key * @param Default * @return */ public boolean getPrefixBoolean(String prefix, String key, boolean Default) { String b = getPrefixProperty(prefix, key, null); if (b == null) { return Default; } return Boolean.parseBoolean(b.trim()); } /** * return the COlor that has the given key = prefix.key or key = key or * default, in that order * @param prefix * @param key * @param Default * @return */ public Color getPrefixColor(String prefix, String key, Color Default) { String c = getPrefixProperty(prefix, key, null); if (c == null) { return Default; } try { return Color.decode(c); } catch (NumberFormatException e) { return Default; } } /** * Return a sub configuration from this instance that has the keys equal to * either prefix.keyPrefix or keyPrefix. The entries of keyPrefix are * added first, so they are the defaults if prefix is not found. * * @param prefix * @param keyPrefix * @return */ public Configuration subConfig(String prefix, String keyPrefix) { Configuration sub = new Configuration(); addToSubConf(sub, prefix.length() > 0 ? prefix + "." + keyPrefix : keyPrefix); return sub; } private void addToSubConf(Configuration subConf, String prefix) { int prefixLen = prefix.length(); for (String k : stringPropertyNames()) { if (k.startsWith(prefix)) { subConf.put(k.substring(prefixLen), getProperty(k)); } } } public Pattern getValueSeparator(String prefix) { synchronized(valueSeparatorMap) { Pattern val = valueSeparatorMap.get(prefix); if (val == null) { val = Pattern.compile("\\s*" + getPrefixProperty(prefix, "ValueSeparator", COMMA_SEPARATOR) + "\\s*"); valueSeparatorMap.put(prefix, val); } return val; } } public static final String[] EMPTY_LIST = new String[0]; public static final String COMMA_SEPARATOR = ","; private static final Logger LOG = Logger.getLogger(Configuration.class.getName()); } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/util/JarServiceProvider.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author subwiz */ public class JarServiceProvider { private static final Logger LOG = Logger.getLogger(JarServiceProvider.class.getName()); private static ClassLoader globalLoader = ClassLoader.getSystemClassLoader(); /** * Prevent anyone from instantiating this class. * Just use the static method */ private JarServiceProvider() { } public static Class loadClass(String className) throws ClassNotFoundException { return globalLoader.loadClass(className); } /** * Return an Object array from the file in META-INF/resources/{classname} * @param cls * @return * @throws java.io.IOException */ public static List getServiceProviders(Class cls) throws IOException { ArrayList l = new ArrayList(); if (globalLoader != null) { String serviceFile = "META-INF/services/" + cls.getName(); Enumeration e = globalLoader.getResources(serviceFile); while (e.hasMoreElements()) { URL u = e.nextElement(); InputStream is = u.openStream(); BufferedReader br = null; try { br = new BufferedReader( new InputStreamReader(is, Charset.forName("UTF-8"))); String str = null; while ((str = br.readLine()) != null) { int commentStartIdx = str.indexOf("#"); if (commentStartIdx != -1) { str = str.substring(0, commentStartIdx); } str = str.trim(); if (str.length() == 0) { continue; } try { Object obj = globalLoader.loadClass(str).newInstance(); l.add(obj); } catch (Exception ex) { LOG.warning("Could not load: " + str); LOG.warning(ex.getMessage()); } } } finally { if (br != null) { br.close(); } } } } return l; } /** * Read a file in the META-INF/services location. File name will be * fully qualified classname, in all lower-case, appended with ".properties" * If no file is found, then a an empty Property instance will be returned * @param clazz * @return Property file read. */ public static Properties readProperties(Class clazz) { return readProperties(clazz.getName()); } /** * Read a file in the META-INF/services named name appended with * ".properties" * If no file is found, then a an empty Property instance will be returned * @param name name of file (use dots to separate subfolders). * @return Property file read. */ public static Properties readProperties(String name) { Properties props = new Properties(); if (globalLoader != null) { InputStream is = null; try { String serviceFile = "META-INF/services/" + name.toLowerCase() + ".properties"; Enumeration locs = globalLoader.getResources(serviceFile); while(locs.hasMoreElements()) { URL loc = locs.nextElement(); if (loc != null) { try { is = loc.openStream(); Properties p = new Properties(); p.load(is); props.putAll(p); } finally { if (is != null) { is.close(); } } } } } catch (IOException ex) { LOG.log(Level.SEVERE, null, ex); } finally { try { // maybe the is was not open coz we did not find the file if (is != null) { is.close(); } } catch (IOException ex) { LOG.log(Level.SEVERE, null, ex); } } } return props; } /** * Read a file in the META-INF/services named name appended with * ".properties", and returns it as a Map * If no file is found, then a an empty Property instance will be returned * @param name name of file (use dots to separate subfolders). * @return Map of keys and values */ public static Map readStringsMap(String name) { Properties props = readProperties(name); HashMap map = new HashMap(); if (props != null) { for (Map.Entry e : props.entrySet()) { map.put(e.getKey().toString(), e.getValue().toString()); } } return map; } public static void setGlobalLoader(ClassLoader loader) { globalLoader = loader; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/bash.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class BashLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public BashLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } private Token token(TokenType type, int pairValue) { return new Token(type, yychar, yylength(), (byte)pairValue); } private static final byte PARAN = 1; private static final byte BRACKET = 2; private static final byte CURLY = 3; private static final byte DO = 4; private static final byte CASE = 5; private static final byte IF = 5; private static final byte INT_EXPR = 6; %} LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] Identifier = [a-zA-Z][a-zA-Z0-9_]* Comment = "#" {InputCharacter}* {LineTerminator}? Shebang = "#!" {InputCharacter}* {LineTerminator}? StringCharacter = [^\r\n\"\\] SingleCharacter = [^\r\n\'\\] BackQuoteChars = [^\r\n\`\\] %% { /* Bash keywords */ "if" { return token(TokenType.KEYWORD, IF); } "fi" { return token(TokenType.KEYWORD, -IF); } "do" { return token(TokenType.KEYWORD, DO); } "done" { return token(TokenType.KEYWORD, -DO); } "case" { return token(TokenType.KEYWORD, CASE); } "esac" { return token(TokenType.KEYWORD, -CASE); } "$((" { return token(TokenType.KEYWORD, INT_EXPR); } "))" { return token(TokenType.KEYWORD, -INT_EXPR); } "(" { return token(TokenType.OPERATOR, PARAN); } ")" { return token(TokenType.OPERATOR, -PARAN); } "{" { return token(TokenType.OPERATOR, CURLY); } "}" { return token(TokenType.OPERATOR, -CURLY); } "[" { return token(TokenType.OPERATOR, BRACKET); } "]" { return token(TokenType.OPERATOR, -BRACKET); } "-eq" | "-ne" | "-lt" | "-gt" | "-ge" | "-le" | ">=" | "<=" | "==" | "!=" | "-z" | "-n" | "=~" | "$" | "#" | "&" | "." | ";" | "+" | "-" | "=" | "/" | "++" | "@" { return token(TokenType.OPERATOR); } "then" | "else" | "elif" | "for" | "in" | "until" | "while" | "break" | "local" | "continue" { return token(TokenType.KEYWORD); } /* string literal */ \"{StringCharacter}+\" | \'{SingleCharacter}+\ { return token(TokenType.STRING); } \`{BackQuoteChars}+\` { return token(TokenType.STRING2); } /* Other commands */ "alias" | "apropos" | "apt" | "aspell" | "awk" | "bash" | "basename" | "bc" | "bg" | "builtin" | "bzip2" | "cal" | "cat" | "cd" | "cfdisk" | "chgrp" | "chmod" | "chown" | "chroot" | "chkconfig" | "cksum" | "clear" | "cmp" | "comm" | "command" | "continue" | "cp" | "cron" | "crontab" | "csplit" | "cut" | "date" | "dc" | "dd" | "ddrescue" | "declare" | "df" | "diff" | "diff3" | "dig" | "dir" | "dircolors" | "dirname" | "dirs" | "dmesg" | "du" | "echo" | "egrep" | "eject" | "enable" | "env" | "ethtool" | "eval" | "exec" | "exit" | "expect" | "expand" | "export" | "expr" | "false" | "fdformat" | "fdisk" | "fg" | "fgrep" | "file" | "find" | "fmt" | "fold" | "format" | "free" | "fsck" | "ftp" | "function" | "gawk" | "getopts" | "grep" | "groups" | "gzip" | "hash" | "head" | "history" | "hostname" | "id" | "ifconfig" | "ifdown" | "ifup" | "import" | "install" | "join" | "kill" | "killall" | "less" | "let" | "ln" | "locate" | "logname" | "logout" | "look" | "lpc" | "lpr" | "lprint" | "lprintd" | "lprintq" | "lprm" | "ls" | "lsof" | "man" | "mkdir" | "mkfifo" | "mkisofs" | "mknod" | "more" | "mount" | "mtools" | "mv" | "mmv" | "netstat" | "nice" | "nl" | "nohup" | "nslookup" | "open" | "op" | "passwd" | "paste" | "pathchk" | "ping" | "popd" | "pr" | "printcap" | "printenv" | "printf" | "ps" | "pushd" | "pwd" | "quota" | "quotacheck" | "quotactl" | "ram" | "rcp" | "read" | "readonly" | "reboot" | "renice" | "remsync" | "return" | "rev" | "rm" | "rmdir" | "rsync" | "screen" | "scp" | "sdiff" | "sed" | "select" | "seq" | "set" | "sftp" | "shift" | "shopt" | "shutdown" | "sleep" | "slocate" | "sort" | "source" | "split" | "ssh" | "strace" | "su" | "sudo" | "sum" | "symlink" | "sync" | "tail" | "tar" | "tee" | "test" | "time" | "times" | "touch" | "top" | "traceroute" | "trap" | "tr" | "true" | "tsort" | "tty" | "type" | "ulimit" | "umask" | "umount" | "unalias" | "uname" | "unexpand" | "uniq" | "units" | "unset" | "unshar" | "useradd" | "usermod" | "users" | "uuencode" | "uudecode" | "v" | "vdir" | "vi" | "vmstat" | "watch" | "wc" | "whereis" | "which" | "who" | "whoami" | "Wget" | "write" | "xargs" | "yes" { return token(TokenType.KEYWORD); } {Identifier} { return token(TokenType.IDENTIFIER); } /* labels */ ":" [a-zA-Z][a-zA-Z0-9_]* { return token(TokenType.TYPE); } /* comments */ {Shebang} { return token(TokenType.COMMENT2); } {Comment} { return token(TokenType.COMMENT); } . | {LineTerminator} { /* skip */ } } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/c.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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. */ /* * Copyright 2006 Arnout Engelen . * Copyright 2000-2006 Omnicore Software, Hans Kratz & Dennis Strein GbR, * Geert Bevin . * Distributed under the terms of either: * - the common development and distribution license (CDDL), v1.0; or * - the GNU Lesser General Public License, v2.1 or later */ package jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class CLexer %extends DefaultLexer %final %unicode %char %type Token %{ public CLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } private Token token(TokenType type, int pairValue) { return new Token(type, yychar, yylength(), (byte)pairValue); } private static final byte PARAN = 1; private static final byte BRACKET = 2; private static final byte CURLY = 3; // These will be used to store Token Start positions and length for Complex // Tokens that need deifferent Lexer States, like STRING int tokenStart; int tokenLength; %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f]+ /* comments */ Comment = {TraditionalComment} | {EndOfLineComment} TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" EndOfLineComment = "//" {InputCharacter}* {LineTerminator}? /* identifiers */ ConstantIdentifier = {SimpleConstantIdentifier} SimpleConstantIdentifier = [#A-Z0-9_]+ Identifier = [:jletter:][:jletterdigit:]* TypeIdentifier = {SimpleTypeIdentifier} SimpleTypeIdentifier = [A-Z][:jletterdigit:]* /* int literals */ DecLiteral = 0 | [1-9][0-9]* {IntegerSuffix} HexLiteral = 0 [xX] 0* {HexDigit}* {IntegerSuffix} HexDigit = [0-9a-fA-F] OctLiteral = 0+ {OctDigit}* {IntegerSuffix} OctDigit = [0-7] IntegerSuffix = [uU]? [lL]? [uU]? /* float literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}|{FLit4}) ([fF]|[dD])? FLit1 = [0-9]+ \. [0-9]* {Exponent}? FLit2 = \. [0-9]+ {Exponent}? FLit3 = [0-9]+ {Exponent} FLit4 = [0-9]+ {Exponent}? Exponent = [eE] [+\-]? [0-9]+ %% { /* keywords */ "break" | "case" | "catch" | "continue" | "default" | "do" | "else" | "for" | "goto" | "enum" | "if" | "inline" | "mutable" | "noinline" | "return" | "safecast" | "sealed" | "selectany" | "sizeof" | "static_cast" | "switch" | "template" | "this" | "thread" | "throw" | "try" | "typedef" | "typeid" | "typename" | "using" | "uuid" | "value" | "virtual" | "while" { return token(TokenType.KEYWORD); } "static" | "struct" | "union" | "volatile" | "register" | "extern" | "const" | "signed" | "unsigned" | "bool" | "char" | "double" | "int" | "long" | "float" | "short" | "void" { return token(TokenType.TYPE); } /* literals */ (\" ( [^\"\n\\] | \\[^\n] )* (\n | \\\n | \")) | (\' ( [^\'\n\\] | \\[^\n] )* (\n | \\\n | \')) { return token(TokenType.STRING); } "true" | "false" | {DecLiteral} | {OctLiteral} | {HexLiteral} | {FloatLiteral} { return token(TokenType.NUMBER); } /* preprocessor symbols */ "#define" | "#elif" | "#else" | "#endif" | "#error" | "#ifdef" | "#ifndef" | "#if" | "#import" | "#include" | "#line" | "#pragma" | "#undef" | "#using" { return token(TokenType.KEYWORD2); } /* separators */ "(" { return token(TokenType.OPERATOR, PARAN); } ")" { return token(TokenType.OPERATOR, -PARAN); } "{" { return token(TokenType.OPERATOR, CURLY); } "}" { return token(TokenType.OPERATOR, -CURLY); } "[" { return token(TokenType.OPERATOR, BRACKET); } "]" { return token(TokenType.OPERATOR, -BRACKET); } /* operators */ "=" | ";" | "," | "." | ">" | "<" | "!" | "~" | "?" | ":" | "+" | "-" | "*" | "/" | "&" | "|" | "^" | ">>" | "<<" | "%" { return token(TokenType.OPERATOR); } {ConstantIdentifier} { return token(TokenType.IDENTIFIER); } {TypeIdentifier} { return token(TokenType.IDENTIFIER); } \n | {Identifier} | {WhiteSpace} { return token(TokenType.IDENTIFIER); } {Comment} { return token(TokenType.COMMENT); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/clojure.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class ClojureLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public ClojureLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } private Token token(TokenType type, int pairValue) { return new Token(type, yychar, yylength(), (byte)pairValue); } private static final byte PARAN = 1; private static final byte BRACKET = 2; private static final byte CURLY = 3; %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f]+ /* comments */ Comment = {EndOfLineComment} EndOfLineComment = ";" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [:jletter:][:jletterdigit:]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* DecLongLiteral = {DecIntegerLiteral} [lL] HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] HexDigit = [0-9a-fA-F] OctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15} OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] OctDigit = [0-7] /* floating point literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? FLit1 = [0-9]+ \. [0-9]* FLit2 = \. [0-9]+ FLit3 = [0-9]+ Exponent = [eE] [+-]? [0-9]+ /* string and character literals */ StringCharacter = [^\r\n\"\\] SingleCharacter = [^\r\n\'\\] %state STRING, CHARLITERAL %% { /* keywords */ "fn" | "fn*" | "if" | "def" | "let" | "let*" | "loop*" | "new" | "nil" | "recur" | "loop" | "do" | "quote" | "the-var" | "identical?" | "throw" | "set!" | "monitor-enter" | "monitor-exit" | "try" | "catch" | "finally" | "in-ns" { return token(TokenType.KEYWORD); } /* Built-ins */ "*agent*" | "*command-line-args*" | "*in*" | "*macro-meta*" | "*ns*" | "*out*" | "*print-meta*" | "*print-readably*" | "*proxy-classes*" | "*warn-on-reflection*" | "+" | "-" | "->" | ".." | "/" | "<" | "<=" | "=" | "==" | ">" | ">=" | "accessor" | "agent" | "agent-errors" | "aget" | "alength" | "all-ns" | "alter" | "and" | "apply" | "array-map" | "aset" | "aset-boolean" | "aset-byte" | "aset-char" | "aset-double" | "aset-float" | "aset-int" | "aset-long" | "aset-short" | "assert" | "assoc" | "await" | "await-for" | "bean" | "binding" | "bit-and" | "bit-not" | "bit-or" | "bit-shift-left" | "bit-shift-right" | "bit-xor" | "boolean" | "butlast" | "byte" | "cast" | "char" | "class" | "clear-agent-errors" | "comment" | "commute" | "comp" | "comparator" | "complement" | "concat" | "cond" | "conj" | "cons" | "constantly" | "construct-proxy" | "contains?" | "count" | "create-ns" | "create-struct" | "cycle" | "dec" | "defmacro" | "defmethod" | "defmulti" | "defn" | "defn-" | "defstruct" | "deref" | "destructure" | "disj" | "dissoc" | "distinct" | "doall" | "doc" | "dorun" | "doseq" | "dosync" | "dotimes" | "doto" | "double" | "drop" | "drop-while" | "ensure" | "eval" | "every?" | "false?" | "ffirst" | "file-seq" | "filter" | "find" | "find-doc" | "find-ns" | "find-var" | "first" | "float" | "flush" | "fnseq" | "for" | "frest" | "gensym" | "gen-class" | "gen-interface" | "get" | "get-proxy-class" | "hash-map" | "hash-set" | "identity" | "if-let" | "import" | "inc" | "instance?" | "int" | "interleave" | "into" | "into-array" | "iterate" | "key" | "keys" | "keyword" | "keyword?" | "last" | "lazy-cat" | "lazy-cons" | "line-seq" | "list" | "list*" | "load" | "load-file" | "locking" | "long" | "macroexpand" | "macroexpand-1" | "make-array" | "map" | "map?" | "mapcat" | "max" | "max-key" | "memfn" | "merge" | "merge-with" | "meta" | "min" | "min-key" | "name" | "namespace" | "neg?" | "newline" | "nil?" | "not" | "not-any?" | "not-every?" | "not=" | "ns-imports" | "ns-interns" | "ns-map" | "ns-name" | "ns-publics" | "ns-refers" | "ns-resolve" | "ns-unmap" | "nth" | "nthrest" | "or" | "partial" | "peek" | "pmap" | "pop" | "pos?" | "pr" | "pr-str" | "print" | "print-doc" | "print-str" | "println" | "println-str" | "prn" | "prn-str" | "proxy" | "proxy-mappings" | "quot" | "rand" | "rand-int" | "range" | "re-find" | "re-groups" | "re-matcher" | "re-matches" | "re-pattern" | "re-seq" | "read" | "read-line" | "reduce" | "ref" | "ref-set" | "refer" | "rem" | "remove-method" | "remove-ns" | "repeat" | "replace" | "replicate" | "require" | "resolve" | "rest" | "resultset-seq" | "reverse" | "rfirst" | "rrest" | "rseq" | "scan" | "second" | "select-keys" | "send" | "send-off" | "seq" | "seq?" | "set" | "short" | "slurp" | "some" | "sort" | "sort-by" | "sorted-map" | "sorted-map-by" | "sorted-set" | "special-symbol?" | "split-at" | "split-with" | "str" | "string?" | "struct" | "struct-map" | "subs" | "subvec" | "symbol" | "symbol?" | "sync" | "take" | "take-nth" | "take-while" | "test" | "time" | "to-array" | "to-array-2d" | "touch" | "tree-seq" | "true?" | "update-proxy" | "val" | "vals" | "var-get" | "var-set" | "var?" | "vector" | "vector?" | "when" | "when-first" | "when-let" | "when-not" | "while" | "with-local-vars" | "with-meta" | "with-open" | "with-out-str" | "xml-seq" | "zero?" | "zipmap" | "repeatedly" | "add-classpath" | "vec" | "hash" { return token(TokenType.KEYWORD2); } /* operators */ "(" { return token(TokenType.OPERATOR, PARAN); } ")" { return token(TokenType.OPERATOR, -PARAN); } "{" { return token(TokenType.OPERATOR, CURLY); } "}" { return token(TokenType.OPERATOR, -CURLY); } "[" { return token(TokenType.OPERATOR, BRACKET); } "]" { return token(TokenType.OPERATOR, -BRACKET); } /* string literal */ \" { yybegin(STRING); tokenStart = yychar; tokenLength = 1; } /* character literal */ \' { yybegin(CHARLITERAL); tokenStart = yychar; tokenLength = 1; } /* numeric literals */ {DecIntegerLiteral} | {DecLongLiteral} | {HexIntegerLiteral} | {HexLongLiteral} | {OctIntegerLiteral} | {OctLongLiteral} | {FloatLiteral} | {DoubleLiteral} | {DoubleLiteral}[dD] { return token(TokenType.NUMBER); } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace} { } /* identifiers */ {Identifier} { return token(TokenType.IDENTIFIER); } } { \" { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {StringCharacter}+ { tokenLength += yylength(); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { \' { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {SingleCharacter}+ { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/cpp.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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. */ /* * Copyright 2006 Arnout Engelen . * Copyright 2000-2006 Omnicore Software, Hans Kratz & Dennis Strein GbR, * Geert Bevin . * Distributed under the terms of either: * - the common development and distribution license (CDDL), v1.0; or * - the GNU Lesser General Public License, v2.1 or later */ package jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class CppLexer %extends DefaultLexer %final %unicode %char %type Token %{ public CppLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } private Token token(TokenType type, int pairValue) { return new Token(type, yychar, yylength(), (byte)pairValue); } private static final byte PARAN = 1; private static final byte BRACKET = 2; private static final byte CURLY = 3; // These will be used to store Token Start positions and length for Complex // Tokens that need deifferent Lexer States, like STRING int tokenStart; int tokenLength; %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] /* comments */ Comment = {TraditionalComment} | {EndOfLineComment} TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" EndOfLineComment = "//" {InputCharacter}* {LineTerminator}? /* identifiers */ ConstantIdentifier = {SimpleConstantIdentifier} SimpleConstantIdentifier = [#A-Z0-9_]+ Identifier = [:jletter:][:jletterdigit:]* /* int literals */ DecLiteral = 0 | [1-9][0-9]* {IntegerSuffix} HexLiteral = 0 [xX] 0* {HexDigit}* {IntegerSuffix} HexDigit = [0-9a-fA-F] OctLiteral = 0+ {OctDigit}* {IntegerSuffix} OctDigit = [0-7] IntegerSuffix = [uU]? [lL]? [uU]? /* float literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}|{FLit4}) ([fF]|[dD])? FLit1 = [0-9]+ \. [0-9]* {Exponent}? FLit2 = \. [0-9]+ {Exponent}? FLit3 = [0-9]+ {Exponent} FLit4 = [0-9]+ {Exponent}? Exponent = [eE] [+\-]? [0-9]+ %% { /* keywords */ "break" | "case" | "catch" | "continue" | "default" | "do" | "else" | "for" | "goto" | "enum" | "if" | "inline" | "mutable" | "noinline" | "return" | "safecast" | "sealed" | "selectany" | "sizeof" | "static_cast" | "switch" | "template" | "this" | "thread" | "throw" | "try" | "typedef" | "typeid" | "typename" | "using" | "uuid" | "value" | "virtual" | "while" | /* C++ Keywords */ "new" | "delete" | "this" | "friend" | "using" | "throw" | "try" | "catch" | "class" | "typename" | "template" | "namespace" { return token(TokenType.KEYWORD); } "static" | "struct" | "union" | "volatile" | "register" | "extern" | "const" | "signed" | "unsigned" | "bool" | "char" | "double" | "int" | "long" | "float" | "short" | "void" | "public" | "protected" | "private" | "virtual" | "inline" | "virtual" | "explicit" | "export" | "bool" | "wchar_t" { return token(TokenType.TYPE); } /* literals */ (\" ( [^\"\n\\] | \\[^\n] )* (\n | \\\n | \")) | (\' ( [^\'\n\\] | \\[^\n] )* (\n | \\\n | \')) { return token(TokenType.STRING); } "true" | "false" | {DecLiteral} | {OctLiteral} | {HexLiteral} | {FloatLiteral} { return token(TokenType.NUMBER); } /* preprocessor symbols */ "#define" | "#elif" | "#else" | "#endif" | "#error" | "#ifdef" | "#ifndef" | "#if" | "#import" | "#include" | "#line" | "#pragma" | "#undef" | "#using" { return token(TokenType.KEYWORD2); } /* separators */ "(" { return token(TokenType.OPERATOR, PARAN); } ")" { return token(TokenType.OPERATOR, -PARAN); } "{" { return token(TokenType.OPERATOR, CURLY); } "}" { return token(TokenType.OPERATOR, -CURLY); } "[" { return token(TokenType.OPERATOR, BRACKET); } "]" { return token(TokenType.OPERATOR, -BRACKET); } /* operators */ "=" | ";" | "," | "." | ">" | "<" | "!" | "~" | "?" | ":" | "+" | "-" | "*" | "/" | "&" | "|" | "^" | "%" | ">>" | "<<" | "operator" | "typeid" | "and" | "bitor" | "or" | "xor" | "compl" | "bitand" | "and_eq" | "or_eq" | "xor_eq" | "not" | "not_eq" { return token(TokenType.OPERATOR); } /** C++ standard and built-in objects */ "cin" | "cout" { return token(TokenType.TYPE2); } {ConstantIdentifier} { return token(TokenType.TYPE); } {Identifier} { return token(TokenType.IDENTIFIER); } {Comment} { return token(TokenType.COMMENT); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/dosbatch.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class DOSBatchLexer %extends DefaultLexer %final %unicode %char %type Token %ignorecase %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public DOSBatchLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } %} StartComment = rem WhiteSpace = [ \t] LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] KeyCharacter = [a-zA-Z0-9._ ] Comment = "rem" {InputCharacter}* {LineTerminator}? %% { /* DOS keywords */ "@" | "echo" | "goto" | "call" | "exit" | "if" | "else" | "for" | "copy" | "set" | "dir" | "cd" | "set" | "errorlevel" { return token(TokenType.KEYWORD); } /* DOS commands */ "append" | "assoc" | "at" | "attrib" | "break" | "cacls" | "cd" | "chcp" | "chdir" | "chkdsk" | "chkntfs" | "cls" | "cmd" | "color" | "comp" | "compact" | "convert" | "copy" | "date" | "del" | "dir" | "diskcomp" | "diskcopy" | "doskey" | "echo" | "endlocal" | "erase" | "fc" | "find" | "findstr" | "format" | "ftype" | "graftabl" | "help" | "keyb" | "label" | "md" | "mkdir" | "mode" | "more" | "move" | "path" | "pause" | "popd" | "print" | "prompt" | "pushd" | "rd" | "recover" | "rem" | "ren" | "rename" | "replace" | "restore" | "rmdir" | "set" | "setlocal" | "shift" | "sort" | "start" | "subst" | "time" | "title" | "tree" | "type" | "ver" | "verify" | "vol" | "xcopy" { return token(TokenType.KEYWORD); } /* labels */ ":" [a-zA-Z][a-zA-Z0-9_]* { return token(TokenType.TYPE); } /* comments */ {Comment} { return token(TokenType.COMMENT); } . | {LineTerminator} { /* skip */ } } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/groovy.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class GroovyLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Default constructor is needed as we will always call the yyreset */ public GroovyLexer() { super(); } /** * Helper method to create and return a new Token of TokenType */ private Token token(TokenType type) { return new Token(type, yychar, yylength()); } private Token token(TokenType type, int pairValue) { return new Token(type, yychar, yylength(), (byte)pairValue); } private static final byte PARAN = 1; private static final byte BRACKET = 2; private static final byte CURLY = 3; %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f] /* comments */ Comment = {TraditionalComment} | {EndOfLineComment} TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" EndOfLineComment = "//" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [:jletter:][:jletterdigit:]* /* Groovy and generally Java types have first UpperCase Letter */ // Type = [:uppercase:][:jletterdigit:]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* DecLongLiteral = {DecIntegerLiteral} [lL] HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] HexDigit = [0-9a-fA-F] OctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15} OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] OctDigit = [0-7] /* floating point literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? FLit1 = [0-9]+ \. [0-9]* FLit2 = \. [0-9]+ FLit3 = [0-9]+ Exponent = [eE] [+-]? [0-9]+ /* string and character literals */ StringCharacter = [^\r\n\"\\\$] SingleCharacter = [^\r\n\'\\] RegexCharacter = [^\r\n\/] %state STRING, CHARLITERAL, REGEX, GSTRING_EXPR, CHARLITERAL, JDOC, JDOC_TAG %state ML_STRING, ML_STRING_EXPR %% { /* keywords */ "abstract" | "boolean" | "break" | "byte" | "case" | "catch" | "char" | "class" | "const" | "continue" | "do" | "double" | "enum" | "else" | "extends" | "final" | "finally" | "float" | "for" | "default" | "implements" | "import" | "instanceof" | "int" | "interface" | "long" | "native" | "new" | "goto" | "if" | "public" | "short" | "super" | "switch" | "synchronized" | "package" | "private" | "protected" | "transient" | "return" | "void" | "static" | "while" | "this" | "throw" | "throws" | "try" | "volatile" | "strictfp" | /* Groovy reserved words not in Java */ "as" | "asssert" | "def" | "in" | "threadsafe" | /* Booleans and null */ "true" | "false" | "null" { return token(TokenType.KEYWORD); } /* Builtin Types and Object Wrappers */ "Boolean" | "Byte" | "Character" | "Double" | "Float" | "Integer" | "Object" | "Short" | "String" | "Void" | "Class" | "Number" | "Package" | "StringBuffer" | "StringBuilder" | "CharSequence" | "Thread" | "Regex" { return token(TokenType.TYPE); } /* Some Java standard Library Types */ "Throwable" | "Cloneable" | "Comparable" | "Serializable" | "Runnable" { return token(TokenType.TYPE); } /* Groovy commonly used methods */ "print" | "println" { return token(TokenType.KEYWORD); } /* Frequently used Standard Exceptions */ "ArithmeticException" | "ArrayIndexOutOfBoundsException" | "ClassCastException" | "ClassNotFoundException" | "CloneNotSupportedException" | "Exception" | "IllegalAccessException" | "IllegalArgumentException" | "IllegalStateException" | "IllegalThreadStateException" | "IndexOutOfBoundsException" | "InstantiationException" | "InterruptedException" | "NegativeArraySizeException" | "NoSuchFieldException" | "NoSuchMethodException" | "NullPointerException" | "NumberFormatException" | "RuntimeException" | "SecurityException" | "StringIndexOutOfBoundsException" | "UnsupportedOperationException" { return token(TokenType.TYPE2); } /* operators */ "(" { return token(TokenType.OPERATOR, PARAN); } ")" { return token(TokenType.OPERATOR, -PARAN); } "{" { return token(TokenType.OPERATOR, CURLY); } "}" { return token(TokenType.OPERATOR, -CURLY); } "[" { return token(TokenType.OPERATOR, BRACKET); } "]" { return token(TokenType.OPERATOR, -BRACKET); } ";" | "," | "." | "@" | "=" | ">" | "<" | "!" | "~" | "?" | ":" | "==" | "<=" | ">=" | "!=" | "&&" | "||" | "++" | "--" | "+" | "-" | "*" | "/" | "&" | "|" | "^" | "%" | "<<" | ">>" | ">>>" | "+=" | "-=" | "*=" | "/=" | "&=" | "|=" | "^=" | "%=" | "<<=" | ">>=" | ">>>=" { return token(TokenType.OPERATOR); } "~=" | "?." { return token(TokenType.OPERATOR); } /* string literal */ \"{3} { yybegin(ML_STRING); tokenStart = yychar; tokenLength = 3; } /* string literal */ \" { yybegin(STRING); tokenStart = yychar; tokenLength = 1; } /* character literal */ \' { yybegin(CHARLITERAL); tokenStart = yychar; tokenLength = 1; } /* numeric literals */ {DecIntegerLiteral} | {DecLongLiteral} | {HexIntegerLiteral} | {HexLongLiteral} | {OctIntegerLiteral} | {OctLongLiteral} | {FloatLiteral} | {DoubleLiteral} | {DoubleLiteral}[dD] { return token(TokenType.NUMBER); } // JavaDoc comments need a state so that we can highlight the @ controls "/**" { yybegin(JDOC); tokenStart = yychar; tokenLength = 3; } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace}+ { /* skip */ } /* identifiers */ {Identifier} { return token(TokenType.IDENTIFIER); } /* Groovy Regex -- state cannot be easily used here due to / by itself being a valid operator. So if we flip into the REGEX state, we cannot distinguish a regular / */ "/" [^*] {RegexCharacter}+ "/" { return token(TokenType.REGEX); } } { \" { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } "${" { yybegin(GSTRING_EXPR); // length also includes the trailing quote int s = tokenStart; int l = tokenLength; tokenStart = yychar; tokenLength = 2; return new Token(TokenType.STRING, s, l); } {StringCharacter}+ { tokenLength += yylength(); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { "}" { yybegin(STRING); // length also includes the trailing quote int s = tokenStart; int l = tokenLength + 1; tokenStart = yychar + 1; tokenLength = 0; return new Token(TokenType.STRING2, s, l); } {StringCharacter} { tokenLength ++; } } { \"{3} { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 3); } "${" { yybegin(ML_STRING_EXPR); // length also includes the trailing quote int s = tokenStart; int l = tokenLength; tokenStart = yychar; tokenLength = 2; return new Token(TokenType.STRING, s, l); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } .|{LineTerminator} { tokenLength += yylength(); } } { "}" { yybegin(ML_STRING); // length also includes the trailing quote int s = tokenStart; int l = tokenLength + 1; tokenStart = yychar + 1; tokenLength = 0; return new Token(TokenType.STRING2, s, l); } .|\n|\r { tokenLength ++; } } { \' { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {SingleCharacter}+ { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { "*/" { yybegin(YYINITIAL); return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2); } "@" { yybegin(JDOC_TAG); int start = tokenStart; tokenStart = yychar; int len = tokenLength; tokenLength = 1; return new Token(TokenType.COMMENT, start, len); } .|\n { tokenLength ++; } } { ([:letter:])+ ":"? { tokenLength += yylength(); } "*/" { yybegin(YYINITIAL); return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2); } .|\n { yybegin(JDOC); // length also includes the trailing quote int start = tokenStart; tokenStart = yychar; int len = tokenLength; tokenLength = 1; return new Token(TokenType.COMMENT2, start, len); } } { "/" { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.REGEX, tokenStart, tokenLength + 1); } {RegexCharacter}+ { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/java.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class JavaLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public JavaLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } private Token token(TokenType type, int pairValue) { return new Token(type, yychar, yylength(), (byte)pairValue); } private static final byte PARAN = 1; private static final byte BRACKET = 2; private static final byte CURLY = 3; %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f]+ /* comments */ Comment = {TraditionalComment} | {EndOfLineComment} TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" EndOfLineComment = "//" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [:jletter:][:jletterdigit:]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* DecLongLiteral = {DecIntegerLiteral} [lL] HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] HexDigit = [0-9a-fA-F] OctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15} OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] OctDigit = [0-7] /* floating point literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? FLit1 = [0-9]+ \. [0-9]* FLit2 = \. [0-9]+ FLit3 = [0-9]+ Exponent = [eE] [+-]? [0-9]+ /* string and character literals */ StringCharacter = [^\r\n\"\\] SingleCharacter = [^\r\n\'\\] %state STRING, CHARLITERAL, JDOC, JDOC_TAG %% { /* keywords */ "abstract" | "boolean" | "break" | "byte" | "case" | "catch" | "char" | "class" | "const" | "continue" | "do" | "double" | "enum" | "else" | "extends" | "final" | "finally" | "float" | "for" | "default" | "implements" | "import" | "instanceof" | "int" | "interface" | "long" | "native" | "new" | "goto" | "if" | "public" | "short" | "super" | "switch" | "synchronized" | "package" | "private" | "protected" | "transient" | "return" | "void" | "static" | "while" | "this" | "throw" | "throws" | "try" | "volatile" | "strictfp" | "true" | "false" | "null" { return token(TokenType.KEYWORD); } /* Java Built in types and wrappers */ "Boolean" | "Byte" | "Character" | "Double" | "Float" | "Integer" | "Object" | "Short" | "Void" | "Class" | "Number" | "Package" | "StringBuffer" | "StringBuilder" | "CharSequence" | "Thread" | "String" { return token(TokenType.TYPE); } /* Some Java standard Library Types */ "Throwable" | "Cloneable" | "Comparable" | "Serializable" | "Runnable" { return token(TokenType.TYPE); } "WARNING" { return token(TokenType.WARNING); } "ERROR" { return token(TokenType.ERROR); } /* Frequently used Standard Exceptions */ "ArithmeticException" | "ArrayIndexOutOfBoundsException" | "ClassCastException" | "ClassNotFoundException" | "CloneNotSupportedException" | "Exception" | "IllegalAccessException" | "IllegalArgumentException" | "IllegalStateException" | "IllegalThreadStateException" | "IndexOutOfBoundsException" | "InstantiationException" | "InterruptedException" | "NegativeArraySizeException" | "NoSuchFieldException" | "NoSuchMethodException" | "NullPointerException" | "NumberFormatException" | "RuntimeException" | "SecurityException" | "StringIndexOutOfBoundsException" | "UnsupportedOperationException" { return token(TokenType.TYPE2); } /* operators */ "(" { return token(TokenType.OPERATOR, PARAN); } ")" { return token(TokenType.OPERATOR, -PARAN); } "{" { return token(TokenType.OPERATOR, CURLY); } "}" { return token(TokenType.OPERATOR, -CURLY); } "[" { return token(TokenType.OPERATOR, BRACKET); } "]" { return token(TokenType.OPERATOR, -BRACKET); } ";" | "," | "." | "=" | ">" | "<" | "!" | "~" | "?" | ":" | "==" | "<=" | ">=" | "!=" | "&&" | "||" | "++" | "--" | "+" | "-" | "*" | "/" | "&" | "|" | "^" | "%" | "<<" | ">>" | ">>>" | "+=" | "-=" | "*=" | "/=" | "&=" | "|=" | "^=" | "%=" | "<<=" | ">>=" | ">>>=" { return token(TokenType.OPERATOR); } /* string literal */ \" { yybegin(STRING); tokenStart = yychar; tokenLength = 1; } /* character literal */ \' { yybegin(CHARLITERAL); tokenStart = yychar; tokenLength = 1; } /* numeric literals */ {DecIntegerLiteral} | {DecLongLiteral} | {HexIntegerLiteral} | {HexLongLiteral} | {OctIntegerLiteral} | {OctLongLiteral} | {FloatLiteral} | {DoubleLiteral} | {DoubleLiteral}[dD] { return token(TokenType.NUMBER); } // JavaDoc comments need a state so that we can highlight the @ controls "/**" { yybegin(JDOC); tokenStart = yychar; tokenLength = 3; } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace} { } /* identifiers */ {Identifier} { return token(TokenType.IDENTIFIER); } } { \" { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {StringCharacter}+ { tokenLength += yylength(); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { \' { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {SingleCharacter}+ { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { "*/" { yybegin(YYINITIAL); return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2); } "@" { yybegin(JDOC_TAG); int start = tokenStart; tokenStart = yychar; int len = tokenLength; tokenLength = 1; return new Token(TokenType.COMMENT, start, len); } .|\n { tokenLength ++; } } { ([:letter:])+ ":"? { tokenLength += yylength(); } "*/" { yybegin(YYINITIAL); return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2); } .|\n { yybegin(JDOC); // length also includes the trailing quote int start = tokenStart; tokenStart = yychar; int len = tokenLength; tokenLength = 1; return new Token(TokenType.COMMENT2, start, len); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/javascript.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class JavaScriptLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public JavaScriptLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f]+ /* comments */ Comment = {TraditionalComment} | {EndOfLineComment} TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" EndOfLineComment = "//" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [:jletter:][:jletterdigit:]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* DecLongLiteral = {DecIntegerLiteral} [lL] HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] HexDigit = [0-9a-fA-F] OctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15} OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] OctDigit = [0-7] /* floating point literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? FLit1 = [0-9]+ \. [0-9]* FLit2 = \. [0-9]+ FLit3 = [0-9]+ Exponent = [eE] [+-]? [0-9]+ /* string and character literals */ StringCharacter = [^\r\n\"\\] %state STRING %% { /* keywords */ "break" | "case" | "catch" | "continue" | "do" | "else" | "finally" | "for" | "default" | "delete" | "new" | "goto" | "if" | "switch" | "return" | "while" | "this" | "try" | "var" | "function" | "with" | "in" | /* boolean literals */ "true" | "false" | /* null literal */ "null" { return token(TokenType.KEYWORD); } /* Built-in Types*/ "Array" | "Boolean" | "RegExp" | "String" | {Identifier} ":" { return token(TokenType.TYPE); } /* operators */ "(" | ")" | "{" | "}" | "[" | "]" | ";" | "," | "." | "=" | ">" | "<" | "!" | "~" | "?" | ":" | "==" | "<=" | ">=" | "!=" | "&&" | "||" | "++" | "--" | "+" | "-" | "*" | "/" | "&" | "|" | "^" | "%" | "<<" | ">>" | ">>>" | "+=" | "-=" | "*=" | "/=" | "&=" | "|=" | "^=" | "%=" | "<<=" | ">>=" | ">>>=" { return token(TokenType.OPERATOR); } /* string literal */ \" { yybegin(STRING); tokenStart = yychar; tokenLength = 1; } /* numeric literals */ {DecIntegerLiteral} | {DecLongLiteral} | {HexIntegerLiteral} | {HexLongLiteral} | {OctIntegerLiteral} | {OctLongLiteral} | {FloatLiteral} | {DoubleLiteral} | {DoubleLiteral}[dD] { return token(TokenType.NUMBER); } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace} { } /* identifiers */ {Identifier} { return token(TokenType.IDENTIFIER); } } { \" { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {StringCharacter}+ { tokenLength += yylength(); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/jflex.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class JFlexLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public JFlexLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f]+ /* comments */ Comment = {TraditionalComment} | {EndOfLineComment} TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" EndOfLineComment = "//" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [:jletter:][:jletterdigit:]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* DecLongLiteral = {DecIntegerLiteral} [lL] HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] HexDigit = [0-9a-fA-F] OctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15} OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] OctDigit = [0-7] /* floating point literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? FLit1 = [0-9]+ \. [0-9]* FLit2 = \. [0-9]+ FLit3 = [0-9]+ Exponent = [eE] [+-]? [0-9]+ /* string and character literals */ StringCharacter = [^\r\n\"\\] SingleCharacter = [^\r\n\'\\] %state STRING, CHARLITERAL, JDOC, JDOC_TAG %% { /* keywords */ "abstract" | "boolean" | "break" | "byte" | "case" | "catch" | "char" | "class" | "const" | "continue" | "do" | "double" | "enum" | "else" | "extends" | "final" | "finally" | "float" | "for" | "default" | "implements" | "import" | "instanceof" | "int" | "interface" | "long" | "native" | "new" | "goto" | "if" | "public" | "short" | "super" | "switch" | "synchronized" | "package" | "private" | "protected" | "transient" | "return" | "void" | "static" | "while" | "this" | "throw" | "throws" | "try" | "volatile" | "strictfp" | "true" | "false" | "null" { return token(TokenType.KEYWORD); } /* JFlex special types */ "<>" | "[:jletter:]" | "[:jletterdigit:]" | "[:letter:]" | "[:digit:]" | "[:uppercase:]" | "[:lowercase:]" | "<" [a-zA-Z][a-zA-Z0-9_]* ">" { return token(TokenType.TYPE2); } /* JFlex Specials */ "%%" | "%{" | "%}" | "%class" | "%implements" | "%extends" | "%public" | "%final" | "%abstract" | "%apiprivate" | "%init{" | "%init}" | "%initthrow{" | "%initthrow}" | "%initthrow" | "%ctorarg" | "%scanerror" | "%buffer" | "%include" | "%function" | "%integer" | "%int" | "%intwrap" | "%yylexthrow{" | "%yylexthrow}" | "%yylexthrow" | "%eofval{" | "%eofval}" | "%eof{" | "%eof}" | "%eofthrow{" | "%eofthrow}" | "%eofthrow" | "%eofclose" | "%debug" | "%standalone" | "%cup" | "%cupsym" | "%cupdebug" | "%byacc" | "%switch" | "%table" | "%pack" | "%7bit" | "%8bit" | "%full" | "%unicode" | "%16bit" | "%caseless" | "%ignorecase" | "%char" | "%line" | "%column" | "%notunix" | "%yyeof" | "%s" | "%state" | "%x" | "%xstate" | "%type" { return token(TokenType.KEYWORD2); } /* Java Built in types and wrappers */ "Boolean" | "Byte" | "Double" | "Float" | "Integer" | "Object" | "Short" | "String" { return token(TokenType.TYPE); } /* operators */ "(" | ")" | "{" | "}" | "[" | "]" | ";" | "," | "." | "=" | ">" | "<" | "!" | "~" | "?" | ":" | "==" | "<=" | ">=" | "!=" | "&&" | "||" | "++" | "--" | "+" | "-" | "*" | "/" | "&" | "|" | "^" | "%" | "<<" | ">>" | ">>>" | "+=" | "-=" | "*=" | "/=" | "&=" | "|=" | "^=" | "%=" | "<<=" | ">>=" | ">>>=" { return token(TokenType.OPERATOR); } /* string literal */ \" { yybegin(STRING); tokenStart = yychar; tokenLength = 1; } /* character literal */ \' { yybegin(CHARLITERAL); tokenStart = yychar; tokenLength = 1; } /* numeric literals */ {DecIntegerLiteral} | {DecLongLiteral} | {HexIntegerLiteral} | {HexLongLiteral} | {OctIntegerLiteral} | {OctLongLiteral} | {FloatLiteral} | {DoubleLiteral} | {DoubleLiteral}[dD] { return token(TokenType.NUMBER); } // JavaDoc comments need a state so that we can highlight the @ controls "/**" { yybegin(JDOC); tokenStart = yychar; tokenLength = 3; } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace} { } /* identifiers */ {Identifier} { return token(TokenType.IDENTIFIER); } } { \" { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {StringCharacter}+ { tokenLength += yylength(); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { \' { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {SingleCharacter}+ { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { "*/" { yybegin(YYINITIAL); return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2); } "@" { yybegin(JDOC_TAG); int start = tokenStart; tokenStart = yychar; int len = tokenLength; tokenLength = 1; return new Token(TokenType.COMMENT, start, len); } .|\n { tokenLength ++; } } { ([:letter:])+ ":"? { tokenLength += yylength(); } "*/" { yybegin(YYINITIAL); return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2); } .|\n { yybegin(JDOC); // length also includes the trailing quote int start = tokenStart; tokenStart = yychar; int len = tokenLength; tokenLength = 1; return new Token(TokenType.COMMENT2, start, len); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/properties.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class PropertiesLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public PropertiesLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } %} StartComment = # WhiteSpace = [ \t] LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] KeyCharacter = [a-zA-Z0-9._ ] %% { {KeyCharacter}+{WhiteSpace}*= { return token(TokenType.KEYWORD); } {StartComment} {InputCharacter}* {LineTerminator}? { return token(TokenType.COMMENT); } . | {LineTerminator} { /* skip */ } } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/python.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class PythonLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public PythonLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } private Token token(TokenType type, int pairValue) { return new Token(type, yychar, yylength(), (byte)pairValue); } private static final byte PARAN = 1; private static final byte BRACKET = 2; private static final byte CURLY = 3; %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f]+ /* comments */ Comment = "#" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [a-zA-Z][a-zA-Z0-9_]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* DecLongLiteral = {DecIntegerLiteral} [lL] HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] HexDigit = [0-9a-fA-F] OctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15} OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] OctDigit = [0-7] /* floating point literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? FLit1 = [0-9]+ \. [0-9]* FLit2 = \. [0-9]+ FLit3 = [0-9]+ Exponent = [eE] [+-]? [0-9]+ /* string and character literals */ StringCharacter = [^\r\n\"\\] %state STRING, ML_STRING %% { /* keywords */ "and" | "as" | "assert" | "break" | "class" | "continue" | "def" | "del" | "elif" | "else" | "except" | "exec" | "finally" | "for" | "from" | "global" | "if" | "import" | "in" | "is" | "lambda" | "not" | "or" | "pass" | "print" | "self" | /* not exactly keyword, but almost */ "raise" | "return" | "try" | "while" | "with" | "yield" { return token(TokenType.KEYWORD); } /* Built-in Types*/ "yield" | "Ellipsis" | "False" | "None" | "NotImplemented" | "True" | "__import__" | "__name__" | "abs" | "apply" | "bool" | "buffer" | "callable" | "chr" | "classmethod" | "cmp" | "coerce" | "compile" | "complex" | "delattr" | "dict" | "dir" | "divmod" | "enumerate" | "eval" | "execfile" | "file" | "filter" | "float" | "frozenset" | "getattr" | "globals" | "hasattr" | "hash" | "help" | "hex" | "id" | "input" | "int" | "intern" | "isinstance" | "issubclass" | "iter" | "len" | "list" | "locals" | "long" | "map" | "max" | "min" | "object" | "oct" | "open" | "ord" | "pow" | "property" | "range" | "raw_input" | "reduce" | "reload" | "repr" | "reversed" | "round" | "set" | "setattr" | "slice" | "sorted" | "staticmethod" | "str" | "sum" | "super" | "tuple" | "type" | "unichr" | "unicode" | "vars" | "xrange" | "zip" { return token(TokenType.TYPE); } /* operators */ "(" { return token(TokenType.OPERATOR, PARAN); } ")" { return token(TokenType.OPERATOR, -PARAN); } "{" { return token(TokenType.OPERATOR, CURLY); } "}" { return token(TokenType.OPERATOR, -CURLY); } "[" { return token(TokenType.OPERATOR, BRACKET); } "]" { return token(TokenType.OPERATOR, -BRACKET); } "+" | "-" | "*" | "**" | "/" | "//" | "%" | "<<" | ">>" | "&" | "|" | "^" | "~" | "<" | ">" | "<=" | ">=" | "==" | "!=" | "<>" | "@" | "," | ":" | "." | "`" | "=" | ";" | "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | ">>=" | "<<=" | "**=" { return token(TokenType.OPERATOR); } /* string literal */ \"{3} { yybegin(ML_STRING); tokenStart = yychar; tokenLength = 3; } \" { yybegin(STRING); tokenStart = yychar; tokenLength = 1; } /* numeric literals */ {DecIntegerLiteral} | {DecLongLiteral} | {HexIntegerLiteral} | {HexLongLiteral} | {OctIntegerLiteral} | {OctLongLiteral} | {FloatLiteral} | {DoubleLiteral} | {FloatLiteral}[jJ] { return token(TokenType.NUMBER); } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace} { } /* identifiers */ {Identifier} { return token(TokenType.IDENTIFIER); } "$" | "?" { return token(TokenType.ERROR); } } { \" { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {StringCharacter}+ { tokenLength += yylength(); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { \"{3} { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 3); } {StringCharacter}+ { tokenLength += yylength(); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { tokenLength ++; } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/ruby.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class RubyLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public RubyLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } private Token token(TokenType type, int pairValue) { return new Token(type, yychar, yylength(), (byte)pairValue); } private static final byte PARAN = 1; private static final byte BRACKET = 2; private static final byte CURLY = 3; private static final byte WORD = 4; %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f]+ /* comments */ Comment = "#" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [a-zA-Z][a-zA-Z0-9_]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* DecLongLiteral = {DecIntegerLiteral} [lL] HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] HexDigit = [0-9a-fA-F] OctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15} OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] OctDigit = [0-7] /* floating point literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? FLit1 = [0-9]+ \. [0-9]* FLit2 = \. [0-9]+ FLit3 = [0-9]+ Exponent = [eE] [+-]? [0-9]+ /* string and character literals */ StringCharacter = [^\r\n\"\\] %state STRING, ML_STRING %% { /* keywords */ "BEGIN" | "ensure" | "assert" | "nil" | "self" | "when" | "END" | "false" | "not" | "super" | "alias" | "defined" | "or" | "then" | "yield" | "and" | "redo" | "true" | "else" | "in" | "rescue" | "undef" | "break" | "elsif" | "module" | "retry" | "unless" | "next" | "return" { return token(TokenType.KEYWORD); } "begin" | "case" | "class" | "def" | "for" | "while" | "until" | "do" | "if" { return token(TokenType.KEYWORD, WORD); } "end" { return token(TokenType.KEYWORD, -WORD); } /* Built-in Types*/ "self" | "nil" | "true" | "false" | "__FILE__" | "__LINE__" { return token(TokenType.TYPE); } /* operators */ "(" { return token(TokenType.OPERATOR, PARAN); } ")" { return token(TokenType.OPERATOR, -PARAN); } "{" { return token(TokenType.OPERATOR, CURLY); } "}" { return token(TokenType.OPERATOR, -CURLY); } "[" { return token(TokenType.OPERATOR, BRACKET); } "]" { return token(TokenType.OPERATOR, -BRACKET); } "+" | "-" | "*" | "**" | "/" | "//" | "%" | "<<" | ">>" | "&" | "|" | "^" | "~" | "<" | ">" | "<=" | ">=" | "==" | "!=" | "<>" | "@" | "," | ":" | "." | ".." | "`" | "=" | ";" | "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | ">>=" | "<<=" | "**=" { return token(TokenType.OPERATOR); } /* string literal */ \"{3} { yybegin(ML_STRING); tokenStart = yychar; tokenLength = 3; } \" { yybegin(STRING); tokenStart = yychar; tokenLength = 1; } /* numeric literals */ {DecIntegerLiteral} | {DecLongLiteral} | {HexIntegerLiteral} | {HexLongLiteral} | {OctIntegerLiteral} | {OctLongLiteral} | {FloatLiteral} | {DoubleLiteral} | {FloatLiteral}[jJ] { return token(TokenType.NUMBER); } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace} { } /* identifiers */ {Identifier}"?" { return token(TokenType.TYPE2); } {Identifier} { return token(TokenType.IDENTIFIER); } } { \" { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {StringCharacter}+ { tokenLength += yylength(); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { \"{3} { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 3); } {StringCharacter}+ { tokenLength += yylength(); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { tokenLength ++; } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/scala.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class ScalaLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public ScalaLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } private Token token(TokenType type, int pairValue) { return new Token(type, yychar, yylength(), (byte)pairValue); } private static final byte PARAN = 1; private static final byte BRACKET = 2; private static final byte CURLY = 3; %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f]+ /* comments */ Comment = {TraditionalComment} | {EndOfLineComment} TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" EndOfLineComment = "//" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [:jletter:][:jletterdigit:]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* DecLongLiteral = {DecIntegerLiteral} [lL] HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] HexDigit = [0-9a-fA-F] OctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15} OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] OctDigit = [0-7] /* floating point literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? FLit1 = [0-9]+ \. [0-9]* FLit2 = \. [0-9]+ FLit3 = [0-9]+ Exponent = [eE] [+-]? [0-9]+ /* string and character literals */ StringCharacter = [^\r\n\"\\] SingleCharacter = [^\r\n\'\\] %state STRING, CHARLITERAL, JDOC, JDOC_TAG %% { /* keywords */ "def" | "import" | "package" | "if" | "then" | "else" | "while" | "for" | "do" | "boolean" | "int" | "double" | "byte" | "short" | "char" | "long" | "float" | "unit" | "val" | "with" | "type" | "var" | "yield" | "return" | "true" | "false" | "null" | "this" | "super" | "String" | "Array" | "private" | "protected" | "override" | "abstract" | "final" | "sealed" | "throw" | "try" | "catch" | "finally" | "extends" { return token(TokenType.KEYWORD); } /* Java Built in types and wrappers */ "object" | "Boolean" | "Byte" | "Character" | "Double" | "Float" | "Integer" | "Object" | "Short" | "Void" | "Class" | "Number" | "Package" | "StringBuffer" | "StringBuilder" | "CharSequence" | "Thread" | "String" { return token(TokenType.TYPE); } /* Some Scala predefines */ "println" { return token(TokenType.KEYWORD2); } /* Some Java standard Library Types */ "Throwable" | "Cloneable" | "Comparable" | "Serializable" | "Runnable" { return token(TokenType.TYPE); } "WARNING" { return token(TokenType.WARNING); } "ERROR" { return token(TokenType.ERROR); } /* operators */ "(" { return token(TokenType.OPERATOR, PARAN); } ")" { return token(TokenType.OPERATOR, -PARAN); } "{" { return token(TokenType.OPERATOR, CURLY); } "}" { return token(TokenType.OPERATOR, -CURLY); } "[" { return token(TokenType.OPERATOR, BRACKET); } "]" { return token(TokenType.OPERATOR, -BRACKET); } ";" | "," | "." | "=" | ">" | "<" | "!" | "~" | "?" | ":" | "==" | "<=" | ">=" | "!=" | "&&" | "||" | "++" | "--" | "+" | "-" | "*" | "/" | "&" | "|" | "^" | "%" | "<<" | ">>" | ">>>" | "+=" | "-=" | "*=" | "/=" | "&=" | "|=" | "^=" | "%=" | "<<=" | ">>=" | ">>>=" { return token(TokenType.OPERATOR); } /* string literal */ \" { yybegin(STRING); tokenStart = yychar; tokenLength = 1; } /* character literal */ \' { yybegin(CHARLITERAL); tokenStart = yychar; tokenLength = 1; } /* numeric literals */ {DecIntegerLiteral} | {DecLongLiteral} | {HexIntegerLiteral} | {HexLongLiteral} | {OctIntegerLiteral} | {OctLongLiteral} | {FloatLiteral} | {DoubleLiteral} | {DoubleLiteral}[dD] { return token(TokenType.NUMBER); } // JavaDoc comments need a state so that we can highlight the @ controls "/**" { yybegin(JDOC); tokenStart = yychar; tokenLength = 3; } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace} { } /* identifiers */ {Identifier} { return token(TokenType.IDENTIFIER); } } { \" { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {StringCharacter}+ { tokenLength += yylength(); } \\[0-3]?{OctDigit}?{OctDigit} { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { \' { yybegin(YYINITIAL); // length also includes the trailing quote return new Token(TokenType.STRING, tokenStart, tokenLength + 1); } {SingleCharacter}+ { tokenLength += yylength(); } /* escape sequences */ \\. { tokenLength += 2; } {LineTerminator} { yybegin(YYINITIAL); } } { "*/" { yybegin(YYINITIAL); return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2); } "@" { yybegin(JDOC_TAG); int start = tokenStart; tokenStart = yychar; int len = tokenLength; tokenLength = 1; return new Token(TokenType.COMMENT, start, len); } .|\n { tokenLength ++; } } { ([:letter:])+ ":"? { tokenLength += yylength(); } "*/" { yybegin(YYINITIAL); return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2); } .|\n { yybegin(JDOC); // length also includes the trailing quote int start = tokenStart; tokenStart = yychar; int len = tokenLength; tokenLength = 1; return new Token(TokenType.COMMENT2, start, len); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/sql.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class SqlLexer %extends DefaultLexer %final %unicode %char %type Token %caseless %{ /** * Default constructor is needed as we will always call the yyreset */ public SqlLexer() { super(); } /** * Helper method to create and return a new Token from of TokenType */ private Token token(TokenType type) { return new Token(type, yychar, yylength()); } %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f] /* comments */ Comment = {EndOfLineComment} EndOfLineComment = "--" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [:jletter:][:jletterdigit:]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* /* floating point literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] FLit1 = [0-9]+ \. [0-9]* FLit2 = \. [0-9]+ FLit3 = [0-9]+ Exponent = [eE] [+-]? [0-9]+ /* string and character literals */ StringCharacter = [^\r\n\"\\] SingleCharacter = [^\r\n\'\\] Reserved = "ADD" | "ALL" | "ALTER" | "ANALYZE" | "AND" | "AS" | "ASC" | "BEFORE" | "BETWEEN" | "BIGINT" | "BINARY" | "BLOB" | "BOTH" | "BY" | "CALL" | "CASCADE" | "CASE" | "CHANGE" | "CHAR" | "CHARACTER" | "CHECK" | "COLLATE" | "COLUMN" | "CONDITION" | "CONSTRAINT" | "CONTINUE" | "CONVERT" | "CREATE" | "CROSS" | "CURSOR" | "DATABASE" | "DATABASES" | "DEC" | "DECIMAL" | "DECLARE" | "DEFAULT" | "DELAYED" | "DELETE" | "DESC" | "DESCRIBE" | "DETERMINISTIC" | "DISTINCT" | "DISTINCTROW" | "DIV" | "DOUBLE" | "DROP" | "DUAL" | "EACH" | "ELSE" | "ELSEIF" | "ENCLOSED" | "ESCAPED" | "EXISTS" | "EXIT" | "EXPLAIN" | "FALSE" | "FETCH" | "FLOAT" | "FLOAT4" | "FLOAT8" | "FOR" | "FORCE" | "FOREIGN" | "FROM" | "FULLTEXT" | "GRANT" | "GROUP" | "HAVING" | "IF" | "IGNORE" | "IN" | "INDEX" | "INFILE" | "INNER" | "INOUT" | "INSENSITIVE" | "INSERT" | "INT" | "INTEGER" | "INTERVAL" | "INTO" | "IS" | "ITERATE" | "JOIN" | "KEY" | "KEYS" | "KILL" | "LEADING" | "LEAVE" | "LEFT" | "LIKE" | "LIMIT" | "LINES" | "LOAD" | "LOCK" | "LONG" | "LOOP" | "MATCH" | "MERGE" | "MOD" | "MODIFIES" | "NATURAL" | "NOT" | "NULL" | "NUMERIC" | "ON" | "OPTIMIZE" | "OPTION" | "OPTIONALLY" | "OR" | "ORDER" | "OUT" | "OUTER" | "OUTFILE" | "PRECISION" | "PRIMARY" | "PROCEDURE" | "PURGE" | "READ" | "READS" | "REAL" | "REFERENCES" | "REGEXP" | "RELEASE" | "RENAME" | "REPEAT" | "REPLACE" | "REQUIRE" | "RESTRICT" | "RETURN" | "REVOKE" | "RIGHT" | "RLIKE" | "SCHEMA" | "SCHEMAS" | "SELECT" | "SENSITIVE" | "SEPARATOR" | "SET" | "SHOW" | "SMALLINT" | "SONAME" | "SPATIAL" | "SPECIFIC" | "SQL" | "SQLEXCEPTION" | "SQLSTATE" | "SQLWARNING" | "STARTING" | "TABLE" | "TERMINATED" | "THEN" | "TO" | "TRAILING" | "TRIGGER" | "TRUE" | "TRUNCATE" | "UNDO" | "UNION" | "UNIQUE" | "UNLOCK" | "UNSIGNED" | "UPDATE" | "USAGE" | "USE" | "USING" | "VALUES" | "VARBINARY" | "VARCHAR" | "VARCHARACTER" | "VARYING" | "WHEN" | "WHERE" | "WHILE" | "WITH" | "WRITE" | "XOR" | "ZEROFILL" %% { /* keywords */ {Reserved} { return token(TokenType.KEYWORD); } /* operators */ "(" | ")" | "{" | "}" | "[" | "]" | ";" | "," | "." | "@" | "=" | ">" | "<" | "!" | "~" | "?" | ":" { return token(TokenType.OPERATOR); } /* string literal */ \"{StringCharacter}+\" | \'{SingleCharacter}+\ { return token(TokenType.STRING); } /* numeric literals */ {DecIntegerLiteral} | {FloatLiteral} { return token(TokenType.NUMBER); } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace}+ { /* skip */ } /* identifiers */ {Identifier} { return token(TokenType.IDENTIFIER); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/tal.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class TALLexer %extends DefaultLexer %final %unicode %char %type Token %caseless %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public TALLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f]+ /* comments */ Comment = {TraditionalComment} | {EndOfLineComment} TraditionalComment = "!" [^\r\n!]* ( "!" | {LineTerminator} ) EndOfLineComment = "--" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [A-Za-z_][A-Za-z0-9\^_]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] HexDigit = [0-9a-fA-F] OctIntegerLiteral = "%" [1-3]? {OctDigit} {1,15} OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] OctDigit = [0-7] FixedLiteral = DecIntegerLiteral [fF] DoubleLiteral = DecIntegerLiteral [dD] /* string and character literals */ StringCharacter = [^\r\n\"\\] SingleCharacter = [^\r\n\'\\] %% { /* keywords */ "begin" | "end" | "struct" | "fieldalign" | "shared" | "shared2" | "literal" | "for" | "do" | "while" | "?page" | "?section" { return token(TokenType.KEYWORD); } "int" | "string" | "int(32)" | "fixed" | "byte" | "float" | "filler" { return token(TokenType.TYPE); } "(" | ")" | "{" | "}" | "[" | "]" | ";" | "," | "." | "=" | ">" | "<" | "!" | "?" | ":" | ":=" | "':='" | "'=:'" | "<>" | "+" | "-" | "*" | "/" | "<<" | ">>" { return token(TokenType.OPERATOR); } /* string literal */ \"{StringCharacter}+\" { return token(TokenType.STRING); } /* character literal */ \'{SingleCharacter}\' { return token(TokenType.STRING); } /* numeric literals */ {DecIntegerLiteral} | {HexIntegerLiteral} | {HexLongLiteral} | {OctIntegerLiteral} | {OctLongLiteral} | {FixedLiteral} | {DoubleLiteral} { return token(TokenType.NUMBER); } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace} { } /* identifiers */ {Identifier} { return token(TokenType.IDENTIFIER); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/xml.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 jsyntaxpane.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class XmlLexer %extends DefaultLexer %final %unicode %char %type Token %{ /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader */ public XmlLexer() { super(); } private Token token(TokenType type) { return new Token(type, yychar, yylength()); } private Token token(TokenType type, int pairValue) { return new Token(type, yychar, yylength(), (byte)pairValue); } private static final byte TAG_OPEN = 1; private static final byte TAG_CLOSE = -1; private static final byte INSTR_OPEN = 2; private static final byte INSTR_CLOSE = -2; private static final byte CDATA_OPEN = 3; private static final byte CDATA_CLOSE = -3; private static final byte COMMENT_OPEN = 4; private static final byte COMMENT_CLOSE = -4; %} %xstate COMMENT, CDATA, TAG, INSTR /* main character classes */ /* white space */ S = (\u0020 | \u0009 | \u000D | \u000A)+ /* characters */ Char = \u0009 | \u000A | \u000D | [\u0020-\uD7FF] | [\uE000-\uFFFD] | [\u10000-\u10FFFF] /* comments */ CommentStart = "" NameStartChar = ":" | [A-Z] | "_" | [a-z] NameStartCharUnicode = [\u00C0-\u00D6] | [\u00D8-\u00F6] | [\u00F8-\u02FF] | [\u0370-\u037D] | [\u037F-\u1FFF] | [\u200C-\u200D] | [\u2070-\u218F] | [\u2C00-\u2FEF] | [\u3001-\uD7FF] | [\uF900-\uFDCF] | [\uFDF0-\uFFFD] | [\u10000-\uEFFFF] NameChar = {NameStartChar} | "-" | "." | [0-9] | \u00B7 NameCharUnicode = [\u0300-\u036F] | [\u0203F-\u2040] Name = {NameStartChar} {NameChar}* NameUnicode = ({NameStartChar}|{NameStartCharUnicode}) ({NameChar}|{NameCharUnicode})* /* XML Processing Instructions */ InstrStart = "" /* CDATA */ CDataStart = "" /* Tags */ OpenTagStart = "<" {Name} OpenTagClose = "/>" OpenTagEnd = ">" CloseTag = "" /* attribute */ Attribute = {Name} "=" /* string and character literals */ DQuoteStringChar = [^\r\n\"] SQuoteStringChar = [^\r\n\'] %% { "&" [a-z]+ ";" | "&#" [:digit:]+ ";" { return token(TokenType.KEYWORD2); } {InstrStart} { yybegin(INSTR); return token(TokenType.TYPE2, INSTR_OPEN); } {OpenTagStart} { yybegin(TAG); return token(TokenType.TYPE, TAG_OPEN); } {CloseTag} { return token(TokenType.TYPE, TAG_CLOSE); } {CommentStart} { yybegin(COMMENT); return token(TokenType.COMMENT2, COMMENT_OPEN); } {CDataStart} { yybegin(CDATA); return token(TokenType.COMMENT2, CDATA_OPEN); } } { {Attribute} { return token(TokenType.IDENTIFIER); } \"{DQuoteStringChar}*\" | \'{SQuoteStringChar}*\' { return token(TokenType.STRING); } {InstrEnd} { yybegin(YYINITIAL); return token(TokenType.TYPE2, INSTR_CLOSE); } } { {Attribute} { return token(TokenType.IDENTIFIER); } \"{DQuoteStringChar}*\" | \'{SQuoteStringChar}*\' { return token(TokenType.STRING); } {OpenTagClose} { yybegin(YYINITIAL); return token(TokenType.TYPE, TAG_CLOSE); } {OpenTagEnd} { yybegin(YYINITIAL); return token(TokenType.TYPE); } } { {CommentEnd} { yybegin(YYINITIAL); return token(TokenType.COMMENT2, COMMENT_CLOSE); } ~{CommentEnd} { yypushback(3); return token(TokenType.COMMENT); } } { {CDataEnd} { yybegin(YYINITIAL); return token(TokenType.COMMENT2, CDATA_CLOSE); } ~{CDataEnd} { yypushback(3); return token(TokenType.COMMENT); } } { /* error fallback */ .|\n { } <> { return null; } } ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/resources/META-INF/services/jsyntaxpane.config.properties ================================================ # # Main Configuration of JSyntaxPane # # ----------------------------------------------------------------------------- # # These will be used by all kits, unless the same key is used for a specific # kit, in which case the specific will be used: # # These are the componets that will be installed be default for any kit, unless # specified otherwise Components = jsyntaxpane.components.PairsMarker, \ jsyntaxpane.components.LineNumbersRuler # This is the color to highlight tokens whenever the cursor is on them TokenMarker.Color = 0xffeeaa # Colors for PairMarkers PairMarker.Color = 0xffbb77 # # Right Margin for LineNumbers border in pixels, Default = 5 LineNumbers.RightMargin = 10 # Foreground for line numbers, Default = Black LineNumbers.Foreground = 0x333300 # Background for line numbers, Default = White LineNumbers.Background = 0xeeeeff # Default color for the Caret, Black CaretColor = 0x000000 # # Actions: # The key is of the format: # Actions.NAME = class, key # where NAME is the name of the action as defined by class.getAction(NAME) # class is the fully qualified class name of the SyntaxAction class. Only # one object of that class will be created for all the actions it provides # and key is the keyboard key to map it to as specified by # KeyStroke.getKeyStroge(String key) # Action.FIND = jsyntaxpane.actions.FindReplaceActions, control F Action.REPLACE = jsyntaxpane.actions.FindReplaceActions, control H Action.FIND_NEXT = jsyntaxpane.actions.FindReplaceActions, F3 Action.GOTO_LINE = jsyntaxpane.actions.GotoLineAction, control G Action.INDENT = jsyntaxpane.actions.IndentAction, TAB Action.UNINDENT = jsyntaxpane.actions.UnindentAction, shift TAB # Action.JAVA_INDENT = jsyntaxpane.actions.JavaIndentAction, ENTER Action.JINDENT = jsyntaxpane.actions.JIndentAction, ENTER Action.UNDO = jsyntaxpane.actions.UndoAction, control Z Action.REDO = jsyntaxpane.actions.RedoAction, control Y Action.DELETE_LINES = jsyntaxpane.actions.DeleteLinesAction, control E Action.DUPLICATE_LINES_UP = jsyntaxpane.actions.DuplicateLinesAction, shift control UP Action.DUPLICATE_LINES_DOWN = jsyntaxpane.actions.DuplicateLinesAction, shift control DOWN # # View configuration: # This controls how text is anti-aliased on the editor control: # see the RenderingHints.VALUE_TEXT_ANTIALIAS.... for details # DEFAULT: use the JRE default (default value) # ON: set to on, let the JRE determine best method for the display # OFF: no AA # GASP: used on GTK # HBGR: # HRGB: # VBGR: # VRGM TextAA = ON # # JavaSyntaxKit # JavaSyntaxKit.Components = jsyntaxpane.components.PairsMarker, \ jsyntaxpane.components.LineNumbersRuler, \ jsyntaxpane.components.TokenMarker JavaSyntaxKit.TokenMarker.TokenTypes = IDENTIFIER, TYPE, TYPE2, TYPE3 # # Performs single color selection (Default = false) # JavaSyntaxKit.SingleColorSelect = true # # DIsplaying of a right margin line. If RightMarginColumn is 0, then no margin # will be displayed JavaSyntaxKit.RightMarginColumn = 80 JavaSyntaxKit.RightMarginColor = 0xdddddd JavaSyntaxKit.Action.PARENTHISIS = jsyntaxpane.actions.PairAction, typed ( JavaSyntaxKit.Action.BRACKETS = jsyntaxpane.actions.PairAction, typed [ JavaSyntaxKit.Action.QUOTE = jsyntaxpane.actions.PairAction, typed ' JavaSyntaxKit.Action.DBL_QUOTE = jsyntaxpane.actions.PairAction, typed " JavaSyntaxKit.Action.CLOSE_CURLY = jsyntaxpane.actions.JUnindentAction, typed } JavaSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH # For completions, you have to define the Action (key to trigger completions): # JavaSyntaxKit.Action.COMPELTION = jsyntaxpane.actions.MapCompletionAction, control SPACE JavaSyntaxKit.Action.COMBO_COMPELTION = jsyntaxpane.actions.ComboCompletionAction, control SPACE # and then the specified completions map in the below file JavaSyntaxKit.Completions.File = jsyntaxpane.javasyntaxkit.completions # # These are the completions to be in the IntelliSense completion dialog # comma separated values. # Vertical bars: if there is one, it will position the cursor. If there are # two, they will be start and end of selection JavaSyntaxKit.COMBO_COMPELTION.Items = public, protected, private, class, static, \ .toString(), .equals(|), .hashCode(), \ JTextField, JEditorPane, JTextPane, JComboBox, JList, JTree, \ jsyntaxpane, .setContentType("text/|lang|"), .setProperty("|key|") # # Other Java type actions for other languages: # JavaScriptSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH GroovySyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH CSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH CppSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH # The LineComments Characters can be enclosed in double quotes if spaces are present # in them GroovySyntaxKit.TOGGLE_COMMENTS.LineComments = "// " # # Other Languages RubySyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control NUMBER_SIGN RubySyntaxKit.TOGGLE_COMMENTS.LineComments = "# " PythonSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control NUMBER_SIGN PythonSyntaxKit.TOGGLE_COMMENTS.LineComments = "# " # ----------------------------------------------------------------------------- # # These are the componets that will be installed for XML # XmlSyntaxKit.Components = jsyntaxpane.components.PairsMarker, \ jsyntaxpane.components.LineNumbersRuler XmlSyntaxKit.PairMarker.Color = 0xffeeaa ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/resources/META-INF/services/jsyntaxpane.groovysyntaxkit.completions.properties ================================================ # This file contains the completions that will be used by the Java Syntax # editor kit. # The keys are the completion strings, and the values are the full expansion # of the text. The | character will set the cursor to that location in # completion string pu=public | pr=private | st=static | cl=class | St=String | fri=for(int i=0; i<10; i++) {\n| sout=System.out.println(|) serr=System.err.println(|) psvm=public static void main(String[] args) {\n| ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/resources/META-INF/services/jsyntaxpane.javasyntaxkit.completions.properties ================================================ # This file contains the completions that will be used by the Java Syntax # editor kit. # The keys are the completion strings, and the values are the full expansion # of the text. The | character will set the cursor to that location in # completion string pu=public | pr=private | st=static | cl=class | St=String | fri=for(int i=0; i<10; i++) {\n| sout=System.out.println(|) serr=System.err.println(|) psvm=public static void main(String[] args) {\n| ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/resources/META-INF/services/jsyntaxpane.kitsfortypes.properties ================================================ # This file contains the default content types and the SyntaxKit class names # that will be used for them. # The keys are content types, and the values are the fully qualified class # names text/c=jsyntaxpane.syntaxkits.CSyntaxKit text/cpp=jsyntaxpane.syntaxkits.CppSyntaxKit text/java=jsyntaxpane.syntaxkits.JavaSyntaxKit text/groovy=jsyntaxpane.syntaxkits.GroovySyntaxKit text/javascript=jsyntaxpane.syntaxkits.JavaScriptSyntaxKit text/xml=jsyntaxpane.syntaxkits.XmlSyntaxKit text/sql=jsyntaxpane.syntaxkits.SqlSyntaxKit text/properties=jsyntaxpane.syntaxkits.PropertiesSyntaxKit text/python=jsyntaxpane.syntaxkits.PythonSyntaxKit text/tal=jsyntaxpane.syntaxkits.TALSyntaxKit text/jflex=jsyntaxpane.syntaxkits.JFlexSyntaxKit text/ruby=jsyntaxpane.syntaxkits.RubySyntaxKit text/scala=jsyntaxpane.syntaxkits.ScalaSyntaxKit text/clojure=jsyntaxpane.syntaxkits.ClojureSyntaxKit text/dosbatch=jsyntaxpane.syntaxkits.DOSBatchSyntaxKit text/bash=jsyntaxpane.syntaxkits.BashSyntaxKit ================================================ FILE: plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/resources/META-INF/services/jsyntaxpane.syntaxstyles.properties ================================================ # These are the various Attributes for each TokenType. # The keys of this map are the TokenType Strings, and the values are: # color (hex, or integer), Font.Style attribute # Style is one of: 0 = plain, 1=bold, 2=italic, 3=bold/italic OPERATOR = 0x000000, 0 KEYWORD = 0x3333ee, 0 KEYWORD2 = 0x3333ee, 3 TYPE = 0x000000, 1 TYPE2 = 0x000000, 3 STRING = 0xcc6600, 0 STRING2 = 0xcc6600, 1 NUMBER = 0x999933, 1 REGEX = 0xcc6600, 0 IDENTIFIER = 0x000000, 0 COMMENT = 0x339933, 2 COMMENT2 = 0x339933, 3 DEFAULT = 0x000000, 0 WARNING = 0xCC0000, 0 ERROR = 0xCC0000, 3 ================================================ FILE: plugins/jsyntaxpane-lib/manifest.mf ================================================ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: false OpenIDE-Module: jsyntaxpane.lib/1 OpenIDE-Module-Install: jsyntaxpane/lib/Installer.class OpenIDE-Module-Localizing-Bundle: jsyntaxpane/lib/Bundle.properties OpenIDE-Module-Provides: org.graalvm.visualvm.editor.SyntaxSupport OpenIDE-Module-Specification-Version: 0.9.4.3 ================================================ FILE: plugins/jsyntaxpane-lib/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/jsyntaxpane-lib/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=6b4ac280 build.xml.script.CRC32=3633b2fc build.xml.stylesheet.CRC32=a56c6a5b@2.73 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=6b4ac280 nbproject/build-impl.xml.script.CRC32=f19940e9 nbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73 ================================================ FILE: plugins/jsyntaxpane-lib/nbproject/project.properties ================================================ is.autoload=true javac.compilerargs=-Xlint -Xlint:-serial javac.source=1.6 license.file=external/jsyntaxpane/APACHE-LICENSE-2.0.txt nbm.homepage=http://code.google.com/p/jsyntaxpane/ nbm.module.author=Ayman Al-Sairafi ================================================ FILE: plugins/jsyntaxpane-lib/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project jsyntaxpane.lib org.openide.modules 7.7.1 org.openide.util.lookup 8.3.1 org.openide.util.ui 9.8 jsyntaxpane jsyntaxpane.actions jsyntaxpane.components jsyntaxpane.lexers jsyntaxpane.syntaxkits jsyntaxpane.util ext/jsyntaxpane-0.9.4-visualvm.jar release/modules/ext/jsyntaxpane-0.9.4-visualvm.jar ================================================ FILE: plugins/jsyntaxpane-lib/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/jsyntaxpane-lib/src/jsyntaxpane/lib/Bundle.properties ================================================ OpenIDE-Module-Display-Category=Libraries OpenIDE-Module-Long-Description=\

\nA very simple to use and extend JEditorKit that supports few grammars. \ The main goal is to make it easy to have nice looking Java Swing Editors with support for Syntax Highlighting. \n\

\n

\n

\nCurrently supported grammars:

\nC, C++, Java, Groovy, JavaScript, XML, SQL, OQL, Properties, Python, Tal, JFlex, Ruby, Scala, Clojure, Dos BAT, Bash\n

OpenIDE-Module-Name=jSyntaxPane-lib OpenIDE-Module-Short-Description=A light-weight syntax highlighting support for swing ================================================ FILE: plugins/jsyntaxpane-lib/src/jsyntaxpane/lib/Installer.java ================================================ /* * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package jsyntaxpane.lib; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.util.JarServiceProvider; import org.openide.modules.ModuleInstall; import org.openide.util.Lookup; /** * Manages a module's lifecycle. Remember that an installer is optional and * often not needed at all. */ public class Installer extends ModuleInstall { @Override public void restored() { JarServiceProvider.setGlobalLoader(Lookup.getDefault().lookup(ClassLoader.class)); DefaultSyntaxKit.initKit(); } } ================================================ FILE: plugins/mbeans/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.mbeans. ================================================ FILE: plugins/mbeans/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.modules.mbeans/2 OpenIDE-Module-Install: org/graalvm/visualvm/modules/mbeans/Install.class OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/mbeans/Bundle.properties OpenIDE-Module-Specification-Version: 2.0 ================================================ FILE: plugins/mbeans/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/mbeans/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=88cd756f build.xml.script.CRC32=c5b2575a build.xml.stylesheet.CRC32=79c3b980 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=88cd756f nbproject/build-impl.xml.script.CRC32=69fdc836 nbproject/build-impl.xml.stylesheet.CRC32=deb65f65 ================================================ FILE: plugins/mbeans/nbproject/project.properties ================================================ # # Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. javac.source=1.5 cp.extra=${tools.jar} license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Luis-Miguel Alventosa module.javadoc.packages=org.graalvm.visualvm.modules.mbeans.* ================================================ FILE: plugins/mbeans/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.mbeans org.graalvm.visualvm.application 2 2.0 org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.tools 2 2.0 org.netbeans.modules.options.api 1 1.5.1 org.openide.awt 6.11.1.1 org.openide.modules 7.3 org.openide.util 9.8 org.openide.util.lookup 8.3.1 org.openide.util.ui 9.8 org.openide.windows 6.18.1 ================================================ FILE: plugins/mbeans/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/BorderedComponent.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicGraphicsUtils; import static javax.swing.SwingConstants.*; import static org.graalvm.visualvm.modules.mbeans.Resources.*; import static org.graalvm.visualvm.modules.mbeans.Utilities.*; @SuppressWarnings("serial") class BorderedComponent extends JPanel implements ActionListener { JButton moreOrLessButton; String valueLabelStr; JLabel label; JComponent comp; boolean collapsed = false; private JPopupMenu popupMenu; private Icon collapseIcon; private Icon expandIcon; private static Image getImage(String name) { Toolkit tk = Toolkit.getDefaultToolkit(); name = "resources/" + name + ".png"; // NOI18N return tk.getImage(BorderedComponent.class.getResource(name)); } public BorderedComponent(String text) { this(text, null, false); } public BorderedComponent(String text, JComponent comp) { this(text, comp, false); } public BorderedComponent(String text, JComponent comp, boolean collapsible) { super(null); this.comp = comp; // Only add border if text is not null if (text != null) { TitledBorder border; if (collapsible) { final JLabel textLabel = new JLabel(text); JPanel borderLabel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0)) { public int getBaseline(int w, int h) { Dimension dim = textLabel.getPreferredSize(); return textLabel.getBaseline(dim.width, dim.height) + textLabel.getY(); } }; borderLabel.add(textLabel); border = new LabeledBorder(borderLabel); textLabel.setForeground(border.getTitleColor()); collapseIcon = new ArrowIcon(SOUTH, textLabel); expandIcon = new ArrowIcon(EAST, textLabel); moreOrLessButton = new JButton(collapseIcon); moreOrLessButton.setContentAreaFilled(false); moreOrLessButton.setBorderPainted(false); moreOrLessButton.setMargin(new Insets(0, 0, 0, 0)); moreOrLessButton.addActionListener(this); String toolTip = getText("LBL_BorderedComponent.moreOrLessButton.toolTip"); // NOI18N moreOrLessButton.setToolTipText(toolTip); borderLabel.add(moreOrLessButton); borderLabel.setSize(borderLabel.getPreferredSize()); add(borderLabel); } else { border = new TitledBorder(text); } setBorder(new CompoundBorder(new FocusBorder(this), border)); } else { setBorder(new FocusBorder(this)); } if (comp != null) { add(comp); } } public void setComponent(JComponent comp) { if (this.comp != null) { remove(this.comp); } this.comp = comp; if (!collapsed) { LayoutManager lm = getLayout(); if (lm instanceof BorderLayout) { add(comp, BorderLayout.CENTER); } else { add(comp); } } revalidate(); } public void setValueLabel(String str) { this.valueLabelStr = str; if (label != null) { label.setText(Resources.getText("LBL_CurrentValue",valueLabelStr)); // NOI18N } } public void actionPerformed(ActionEvent ev) { if (collapsed) { if (label != null) { remove(label); } add(comp); moreOrLessButton.setIcon(collapseIcon); } else { remove(comp); if (valueLabelStr != null) { if (label == null) { label = new JLabel(Resources.getText("LBL_CurrentValue", // NOI18N valueLabelStr)); } add(label); } moreOrLessButton.setIcon(expandIcon); } collapsed = !collapsed; JComponent container = (JComponent)getParent(); if (container != null && container.getLayout() instanceof VariableGridLayout) { ((VariableGridLayout)container.getLayout()).setFillRow(this, !collapsed); container.revalidate(); } } public Dimension getMinimumSize() { if (getLayout() != null) { // A layout manager has been set, so delegate to it return super.getMinimumSize(); } if (moreOrLessButton != null) { Dimension d = moreOrLessButton.getMinimumSize(); Insets i = getInsets(); d.width += i.left + i.right; d.height += i.top + i.bottom; return d; } else { return super.getMinimumSize(); } } public void doLayout() { if (getLayout() != null) { // A layout manager has been set, so delegate to it super.doLayout(); return; } Dimension d = getSize(); Insets i = getInsets(); if (collapsed) { if (label != null) { Dimension p = label.getPreferredSize(); label.setBounds(i.left, i.top + (d.height - i.top - i.bottom - p.height) / 2, p.width, p.height); } } else { if (comp != null) { comp.setBounds(i.left, i.top, d.width - i.left - i.right, d.height - i.top - i.bottom); } } } private static class ArrowIcon implements Icon { private int direction; private JLabel textLabel; public ArrowIcon(int direction, JLabel textLabel) { this.direction = direction; this.textLabel = textLabel; } public void paintIcon(Component c, Graphics g, int x, int y) { int w = getIconWidth(); int h = w; Polygon p = new Polygon(); switch (direction) { case EAST: p.addPoint(x + 2, y); p.addPoint(x + w - 2, y + h / 2); p.addPoint(x + 2, y + h - 1); break; case SOUTH: p.addPoint(x, y + 2); p.addPoint(x + w / 2, y + h - 2); p.addPoint(x + w - 1, y + 2); break; } g.fillPolygon(p); } public int getIconWidth() { return getIconHeight(); } public int getIconHeight() { Graphics g = textLabel.getGraphics(); if (g != null) { int h = g.getFontMetrics(textLabel.getFont()).getAscent() * 6/10; if (h % 2 == 0) { h += 1; // Make it odd } return h; } else { return 7; } } } /** * A subclass of TitledBorder which implements an arbitrary border * with the addition of a JComponent (JLabel, JPanel, etc) in the * default position. *

* If the border property value is not * specified in the constuctor or by invoking the appropriate * set method, the property value will be defined by the current * look and feel, using the following property name in the * Defaults Table: *

    *
  • "TitledBorder.border" *
*/ protected static class LabeledBorder extends TitledBorder { protected JComponent label; private Point compLoc = new Point(); /** * Creates a LabeledBorder instance. * * @param label the label the border should display */ public LabeledBorder(JComponent label) { this(null, label); } /** * Creates a LabeledBorder instance with the specified border * and an empty label. * * @param border the border */ public LabeledBorder(Border border) { this(border, null); } /** * Creates a LabeledBorder instance with the specified border and * label. * * @param border the border * @param label the label the border should display */ public LabeledBorder(Border border, JComponent label) { super(border); this.label = label; if (label instanceof JLabel && label.getForeground() instanceof ColorUIResource) { label.setForeground(getTitleColor()); } } /** * Paints the border for the specified component with the * specified position and size. * @param c the component for which this border is being painted * @param g the paint graphics * @param x the x position of the painted border * @param y the y position of the painted border * @param width the width of the painted border * @param height the height of the painted border */ public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Border border = getBorder(); if (label == null) { if (border != null) { border.paintBorder(c, g, x, y, width, height); } return; } Rectangle grooveRect = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING, width - (EDGE_SPACING * 2), height - (EDGE_SPACING * 2)); Dimension labelDim = label.getPreferredSize(); int baseline = label.getBaseline(labelDim.width, labelDim.height); int ascent = Math.max(0, baseline); int descent = labelDim.height - ascent; int diff; Insets insets; if (border != null) { insets = border.getBorderInsets(c); } else { insets = new Insets(0, 0, 0, 0); } diff = Math.max(0, ascent/2 + TEXT_SPACING - EDGE_SPACING); grooveRect.y += diff; grooveRect.height -= diff; compLoc.y = grooveRect.y + insets.top/2 - (ascent + descent) / 2 - 1; int justification; if (c.getComponentOrientation().isLeftToRight()) { justification = LEFT; } else { justification = RIGHT; } switch (justification) { case LEFT: compLoc.x = grooveRect.x + TEXT_INSET_H + insets.left; break; case RIGHT: compLoc.x = (grooveRect.x + grooveRect.width - (labelDim.width + TEXT_INSET_H + insets.right)); break; } // If title is positioned in middle of border AND its fontsize // is greater than the border's thickness, we'll need to paint // the border in sections to leave space for the component's background // to show through the title. // if (border != null) { if (grooveRect.y > compLoc.y - ascent) { Rectangle clipRect = new Rectangle(); // save original clip Rectangle saveClip = g.getClipBounds(); // paint strip left of text clipRect.setBounds(saveClip); if (computeIntersection(clipRect, x, y, compLoc.x-1-x, height)) { g.setClip(clipRect); border.paintBorder(c, g, grooveRect.x, grooveRect.y, grooveRect.width, grooveRect.height); } // paint strip right of text clipRect.setBounds(saveClip); if (computeIntersection(clipRect, compLoc.x+ labelDim.width +1, y, x+width-(compLoc.x+ labelDim.width +1), height)) { g.setClip(clipRect); border.paintBorder(c, g, grooveRect.x, grooveRect.y, grooveRect.width, grooveRect.height); } // paint strip below text clipRect.setBounds(saveClip); if (computeIntersection(clipRect, compLoc.x - 1, compLoc.y + ascent + descent, labelDim.width + 2, y + height - compLoc.y - ascent - descent)) { g.setClip(clipRect); border.paintBorder(c, g, grooveRect.x, grooveRect.y, grooveRect.width, grooveRect.height); } // restore clip g.setClip(saveClip); } else { border.paintBorder(c, g, grooveRect.x, grooveRect.y, grooveRect.width, grooveRect.height); } label.setLocation(compLoc); label.setSize(labelDim); } } /** * Reinitialize the insets parameter with this Border's current Insets. * @param c the component for which this border insets value applies * @param insets the object to be reinitialized */ public Insets getBorderInsets(Component c, Insets insets) { int height = 16; Border border = getBorder(); if (border != null) { if (border instanceof AbstractBorder) { ((AbstractBorder)border).getBorderInsets(c, insets); } else { // Can't reuse border insets because the Border interface // can't be enhanced. Insets i = border.getBorderInsets(c); insets.top = i.top; insets.right = i.right; insets.bottom = i.bottom; insets.left = i.left; } } else { insets.left = insets.top = insets.right = insets.bottom = 0; } insets.left += EDGE_SPACING + TEXT_SPACING; insets.right += EDGE_SPACING + TEXT_SPACING; insets.top += EDGE_SPACING + TEXT_SPACING; insets.bottom += EDGE_SPACING + TEXT_SPACING; if (c == null || label == null) { return insets; } insets.top += label.getHeight(); return insets; } /** * Returns the label of the labeled border. */ public JComponent getLabel() { return label; } /** * Sets the title of the titled border. * param title the title for the border */ public void setLabel(JComponent label) { this.label = label; } /** * Returns the minimum dimensions this border requires * in order to fully display the border and title. * @param c the component where this border will be drawn */ public Dimension getMinimumSize(Component c) { Insets insets = getBorderInsets(c); Dimension minSize = new Dimension(insets.right + insets.left, insets.top + insets.bottom); minSize.width += label.getWidth(); return minSize; } private static boolean computeIntersection(Rectangle dest, int rx, int ry, int rw, int rh) { int x1 = Math.max(rx, dest.x); int x2 = Math.min(rx + rw, dest.x + dest.width); int y1 = Math.max(ry, dest.y); int y2 = Math.min(ry + rh, dest.y + dest.height); dest.x = x1; dest.y = y1; dest.width = x2 - x1; dest.height = y2 - y1; if (dest.width <= 0 || dest.height <= 0) { return false; } return true; } } protected static class FocusBorder extends AbstractBorder implements FocusListener { private Component comp; private Color focusColor; private boolean focusLostTemporarily = false; public FocusBorder(Component comp) { this.comp = comp; comp.addFocusListener(this); // This is the best guess for a L&F specific color focusColor = UIManager.getColor("TabbedPane.focus"); // NOI18N } public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { if (comp.hasFocus() || focusLostTemporarily) { Color color = g.getColor(); g.setColor(focusColor); BasicGraphicsUtils.drawDashedRect(g, x, y, width, height); g.setColor(color); } } public Insets getBorderInsets(Component c, Insets insets) { insets.set(2, 2, 2, 2); return insets; } public void focusGained(FocusEvent e) { comp.repaint(); } public void focusLost(FocusEvent e) { // We will still paint focus even if lost temporarily focusLostTemporarily = e.isTemporary(); if (!focusLostTemporarily) { comp.repaint(); } } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Bundle.properties ================================================ # # Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Tools OpenIDE-Module-Long-Description=\ The MBeans plugin integrates JConsole's MBeans tab functionality into VisualVM. OpenIDE-Module-Name=VisualVM-MBeans OpenIDE-Module-Short-Description=MBeans LBL_1_day=\ 1 day LBL_1_hour=\ 1 hour LBL_1_min=\ 1 min LBL_1_month=\ 1 month LBL_1_year=\ 1 year LBL_2_hours=\ 2 hours LBL_3_hours=\ 3 hours LBL_3_months=\ 3 months LBL_5_min=\ 5 min LBL_6_hours=\ 6 hours LBL_6_months=\ 6 months LBL_7_days=\ 7 days LBL_10_min=10 min LBL_12_hours=12 hours LBL_30_min=30 min LBL_<=< LBL_<<=<< LBL_>=> LBL_ACTION=ACTION LBL_ACTION_INFO=ACTION_INFO LBL_All=All LBL_Attribute=Attribute LBL_AttributeValue=Attribute value LBL_AttributeValues=Attribute values LBL_Attributes=Attributes LBL_BorderedComponent.moreOrLessButton.toolTip=Toggle to show more or less information LBL_Chart=Chart LBL_Chart.mnemonic='C' LBL_ClassName=ClassName LBL_ConnectionNotEstablished=Data not available because JMX connection to the JMX agent could not be established. LBL_Constructor=Constructor LBL_CurrentValue=Current value: {0} LBL_DoubleClickToExpandCollapse=Double click to expand/collapse LBL_DoubleClickToVisualize=Double click to visualize LBL_Description=Description LBL_Descriptor=Descriptor LBL_Details=Details LBL_DimensionIsNotSupported=Dimension is not supported LBL_DiscardChart=Discard chart LBL_DurationDaysHoursMinutes={0,choice,1#{0,number,integer} day |1.0<{0,number,integer} days }{1,choice,0<{1,number,integer} hours |1#{1,number,integer} hour |1<{1,number,integer} hours }{2,choice,0<{2,number,integer} minutes|1#{2,number,integer} minute|1.0<{2,number,integer} minutes} LBL_DurationHoursMinutes={0,choice,1#{0,number,integer} hour |1<{0,number,integer} hours }{1,choice,0<{1,number,integer} minutes|1#{1,number,integer} minute|1.0<{1,number,integer} minutes} LBL_DurationMinutes={0,choice,1#{0,number,integer} minute|1.0<{0,number,integer} minutes} LBL_DurationSeconds={0} seconds LBL_EmptyArray=Empty array LBL_Error=Error LBL_Event=Event LBL_FileChooser.fileExists.cancelOption=Cancel LBL_FileChooser.fileExists.message=
File already exists:
{0}
Do you want to replace it? LBL_FileChooser.fileExists.okOption=Replace LBL_FileChooser.fileExists.title=File Exists LBL_FileChooser.savedFile=Saved to file:
{0}
({1} bytes) LBL_FileChooser.saveFailed.message=
Save to file failed:
{0}
{1} LBL_FileChooser.saveFailed.title=Save Failed LBL_Impact=Impact LBL_Info=Info LBL_INFO=INFO LBL_Is=Is LBL_MBeanAttributeInfo=MBeanAttributeInfo LBL_MBeanInfo=MBeanInfo LBL_MBeanNotificationInfo=MBeanNotificationInfo LBL_MBeanOperationInfo=MBeanOperationInfo LBL_MBeans=MBeans LBL_MBeansBrowser=MBeans Browser LBL_MBeansTab.clearNotificationsButton=Clear LBL_MBeansTab.clearNotificationsButton.mnemonic='C' LBL_MBeansTab.clearNotificationsButton.toolTip=Clear notifications LBL_MBeansTab.compositeNavigationMultiple=Composite Navigation {0}/{1} LBL_MBeansTab.compositeNavigationSingle=Composite Navigation LBL_MBeansTab.refreshAttributesButton=Refresh LBL_MBeansTab.refreshAttributesButton.mnemonic='R' LBL_MBeansTab.refreshAttributesButton.toolTip=Refresh attributes LBL_MBeansTab.subscribeNotificationsButton=Subscribe LBL_MBeansTab.subscribeNotificationsButton.mnemonic='S' LBL_MBeansTab.subscribeNotificationsButton.toolTip=Start listening for notifications LBL_MBeansTab.tabularNavigationMultiple=Tabular Navigation {0}/{1} LBL_MBeansTab.tabularNavigationSingle=Tabular Navigation LBL_MBeansTab.unsubscribeNotificationsButton=Unsubscribe LBL_MBeansTab.unsubscribeNotificationsButton.mnemonic='U' LBL_MBeansTab.unsubscribeNotificationsButton.toolTip=Stop listening for notifications LBL_Message=Message LBL_Metadata=Metadata LBL_MethodSuccessfullyInvoked=Method successfully invoked LBL_Name=Name LBL_Notification=Notification LBL_NotificationBuffer=Notification buffer LBL_Notifications=Notifications LBL_NotifTypes=NotifTypes LBL_ObjectName=ObjectName LBL_Operation=Operation LBL_OperationInvocation=Operation invocation LBL_OperationReturnValue=Operation return value LBL_Operations=Operations LBL_Parameter=Parameter LBL_Plotter.accessibleName=Chart LBL_Plotter.accessibleName.keyAndValue={0}={1}\n LBL_Plotter.accessibleName.noData=No data plotted. LBL_Plotter.saveAsMenuItem=Save data as... LBL_Plotter.saveAsMenuItem.mnemonic='a' LBL_Plotter.timeRangeMenu=Time Range LBL_Plotter.timeRangeMenu.mnemonic='T' LBL_ProblemAddingListener=Problem adding listener LBL_ProblemDisplayingMBean=Problem displaying MBean LBL_ProblemInvoking=Problem invoking LBL_ProblemRemovingListener=Problem removing listener LBL_ProblemSettingAttribute=Problem setting attribute LBL_Readable=Readable LBL_ReturnType=ReturnType LBL_SeqNum=SeqNum LBL_SizeBytes={0,number,integer} bytes LBL_SizeGb={0} Gb LBL_SizeKb={0} Kb LBL_SizeMb={0} Mb LBL_Source=Source LBL_TimeStamp=TimeStamp LBL_Type=Type LBL_Unavailable=Unavailable LBL_UNKNOWN=UNKNOWN LBL_UserData=UserData LBL_Value=Value LBL_Writable=Writable LBL_expand=expand LBL_kbytes={0} kbytes LBL_plot=plot LBL_visualize=visualize ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Formatter.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.text.*; import java.util.*; import static org.graalvm.visualvm.modules.mbeans.Resources.*; class Formatter { final static long SECOND = 1000; final static long MINUTE = 60 * SECOND; final static long HOUR = 60 * MINUTE; final static long DAY = 24 * HOUR; final static String cr = System.getProperty("line.separator"); // NOI18N final static DateFormat timeDF = new SimpleDateFormat("HH:mm"); // NOI18N private final static DateFormat timeWithSecondsDF = new SimpleDateFormat("HH:mm:ss"); // NOI18N private final static DateFormat dateDF = new SimpleDateFormat("yyyy-MM-dd"); // NOI18N private final static String decimalZero = new DecimalFormatSymbols().getDecimalSeparator() + "0"; // NOI18N static String formatTime(long t) { String str; if (t < 1 * MINUTE) { String seconds = String.format("%.3f", t / (double)SECOND); // NOI18N str = Resources.getText("LBL_DurationSeconds", seconds); // NOI18N } else { long remaining = t; long days = remaining / DAY; remaining %= 1 * DAY; long hours = remaining / HOUR; remaining %= 1 * HOUR; long minutes = remaining / MINUTE; if (t >= 1 * DAY) { str = Resources.getText("LBL_DurationDaysHoursMinutes", // NOI18N days, hours, minutes); } else if (t >= 1 * HOUR) { str = Resources.getText("LBL_DurationHoursMinutes", // NOI18N hours, minutes); } else { str = Resources.getText("LBL_DurationMinutes", minutes); // NOI18N } } return str; } static String formatNanoTime(long t) { long ms = t / 1000000; return formatTime(ms); } static String formatClockTime(long time) { return timeDF.format(time); } static String formatDate(long time) { return dateDF.format(time); } static String formatDateTime(long time) { return dateDF.format(time) + " " + timeWithSecondsDF.format(time); // NOI18N } static DateFormat getDateTimeFormat(String key) { String dtfStr = getText(key); int dateStyle = -1; int timeStyle = -1; if (dtfStr.startsWith("SHORT")) { // NOI18N dateStyle = DateFormat.SHORT; } else if (dtfStr.startsWith("MEDIUM")) { // NOI18N dateStyle = DateFormat.MEDIUM; } else if (dtfStr.startsWith("LONG")) { // NOI18N dateStyle = DateFormat.LONG; } else if (dtfStr.startsWith("FULL")) { // NOI18N dateStyle = DateFormat.FULL; } if (dtfStr.endsWith("SHORT")) { // NOI18N timeStyle = DateFormat.SHORT; } else if (dtfStr.endsWith("MEDIUM")) { // NOI18N timeStyle = DateFormat.MEDIUM; } else if (dtfStr.endsWith("LONG")) { // NOI18N timeStyle = DateFormat.LONG; } else if (dtfStr.endsWith("FULL")) { // NOI18N timeStyle = DateFormat.FULL; } if (dateStyle != -1 && timeStyle != -1) { return DateFormat.getDateTimeInstance(dateStyle, timeStyle); } else if (dtfStr.length() > 0) { return new SimpleDateFormat(dtfStr); } else { return DateFormat.getDateTimeInstance(); } } static double toExcelTime(long time) { // Excel is bug compatible with Lotus 1-2-3 and pretends // that 1900 was a leap year, so count from 1899-12-30. // Note that the month index is zero-based in Calendar. Calendar cal = new GregorianCalendar(1899, 11, 30); // Adjust for the fact that now may be DST but then wasn't Calendar tmpCal = new GregorianCalendar(); tmpCal.setTimeInMillis(time); int dst = tmpCal.get(Calendar.DST_OFFSET); if (dst > 0) { cal.set(Calendar.DST_OFFSET, dst); } long millisSince1900 = time - cal.getTimeInMillis(); double value = (double)millisSince1900 / (24 * 60 * 60 * 1000); return value; } static String[] formatKByteStrings(long... bytes) { int n = bytes.length; for (int i = 0; i < n; i++) { if (bytes[i] > 0) { bytes[i] /= 1024; } } String[] strings = formatLongs(bytes); for (int i = 0; i < n; i++) { strings[i] = getText("LBL_kbytes", strings[i]); // NOI18N } return strings; } static String formatKBytes(long bytes) { if (bytes == -1) { return getText("LBL_kbytes", "-1"); // NOI18N } long kb = bytes / 1024; return getText("LBL_kbytes", justify(kb, 10)); // NOI18N } static String formatBytes(long v, boolean html) { return formatBytes(v, v, html); } static String formatBytes(long v, long vMax) { return formatBytes(v, vMax, false); } static String formatBytes(long v, long vMax, boolean html) { String s; int exp = (int)Math.log10((double)vMax); if (exp < 3) { s = Resources.getText("LBL_SizeBytes", v); // NOI18N } else if (exp < 6) { s = Resources.getText("LBL_SizeKb", trimDouble(v / Math.pow(10.0, 3))); // NOI18N } else if (exp < 9) { s = Resources.getText("LBL_SizeMb", trimDouble(v / Math.pow(10.0, 6))); // NOI18N } else { s = Resources.getText("LBL_SizeGb", trimDouble(v / Math.pow(10.0, 9))); // NOI18N } if (html) { s = s.replace(" ", " "); // NOI18N } return s; } /* * Return the input value rounded to one decimal place. If after * rounding the string ends in the (locale-specific) decimal point * followed by a zero then trim that off as well. */ private static String trimDouble(double d) { String s = String.format("%.1f", d); // NOI18N if (s.length() > 3 && s.endsWith(decimalZero)) { s = s.substring(0, s.length()-2); } return s; } static String formatLong(long value) { return String.format("%,d", value); // NOI18N } static String[] formatLongs(long... longs) { int n = longs.length; int size = 0; String[] strings = new String[n]; for (int i = 0; i < n; i++) { strings[i] = formatLong(longs[i]); size = Math.max(size, strings[i].length()); } for (int i = 0; i < n; i++) { strings[i] = justify(strings[i], size); } return strings; } // A poor attempt at right-justifying for numerical data static String justify(long value, int size) { return justify(formatLong(value), size); } static String justify(String str, int size) { StringBuffer buf = new StringBuffer(); buf.append(""); // NOI18N int n = size - str.length(); for (int i = 0; i < n; i++) { buf.append(" "); // NOI18N } buf.append(str); buf.append(""); // NOI18N return buf.toString(); } static String newRow(String label, String value) { return newRow(label, value, 2); } static String newRow(String label, String value, int columnPerRow) { if (label == null) { label = ""; // NOI18N } else { label += ": "; // NOI18N } label = "" + label; // NOI18N value = " " + value; // NOI18N return "" + label + value + ""; // NOI18N } static String newRow(String label1, String value1, String label2, String value2) { label1 = "" + label1 + ": "; // NOI18N value1 = "" + value1; // NOI18N label2 = "" + label2 + ": "; // NOI18N value2 = "" + value2; // NOI18N return "" + label1 + value1 + label2 + value2 + ""; // NOI18N } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/IconManager.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.Image; import javax.swing.Icon; import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; class IconManager { public static Icon MBEAN = getSmallIcon(getImage("mbean.gif")); // NOI18N public static Icon MBEANSERVERDELEGATE = getSmallIcon(getImage("mbeanserverdelegate.gif")); // NOI18N public static Icon DEFAULT_XOBJECT = getSmallIcon(getImage("xobject.gif")); // NOI18N private static ImageIcon getImage(String img) { return new ImageIcon(ImageUtilities.loadImage("org/graalvm/visualvm/modules/mbeans/ui/resources/" + img, true)); // NOI18N } private static ImageIcon getSmallIcon(ImageIcon icon) { return new ImageIcon( icon.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH)); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Install.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import org.openide.modules.ModuleInstall; /** * Manages a module's lifecycle. Remember that an installer is optional and * often not needed at all. * * * @author Tomas Hurka */ public class Install extends ModuleInstall { @Override public void restored() { MBeansViewsSupport.sharedInstance(); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansAttributesView.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.BorderLayout; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.JScrollPane; /** * * @author Jiri Sedlacek */ class MBeansAttributesView extends JPanel { private MBeansTab mbeansTab; public MBeansAttributesView(MBeansTab mbeansTab) { this.mbeansTab = mbeansTab; initComponents(); } private void initComponents() { setLayout(new BorderLayout()); setOpaque(false); JPanel attributes = mbeansTab.getAttributesPanel(); JScrollPane attributesScrollPane = new JScrollPane(attributes, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); attributesScrollPane.setViewportBorder(BorderFactory.createEmptyBorder()); add(attributesScrollPane, BorderLayout.CENTER); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansMetadataView.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.BorderLayout; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.JScrollPane; /** * * @author Jiri Sedlacek */ class MBeansMetadataView extends JPanel { private MBeansTab mbeansTab; public MBeansMetadataView(MBeansTab mbeansTab) { this.mbeansTab = mbeansTab; initComponents(); } private void initComponents() { setLayout(new BorderLayout()); setOpaque(false); JPanel metadata = mbeansTab.getMetadataPanel(); JScrollPane metadataScrollPane = new JScrollPane(metadata, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); metadataScrollPane.setViewportBorder(BorderFactory.createEmptyBorder()); add(metadataScrollPane, BorderLayout.CENTER); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansNotificationsView.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.BorderLayout; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.JScrollPane; /** * * @author Jiri Sedlacek */ class MBeansNotificationsView extends JPanel { private MBeansTab mbeansTab; public MBeansNotificationsView(MBeansTab mbeansTab) { this.mbeansTab = mbeansTab; initComponents(); } private void initComponents() { setLayout(new BorderLayout()); setOpaque(false); JPanel notifications = mbeansTab.getNotificationsPanel(); JScrollPane notificationsScrollPane = new JScrollPane(notifications, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); notificationsScrollPane.setViewportBorder(BorderFactory.createEmptyBorder()); add(notificationsScrollPane, BorderLayout.CENTER); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansOperationsView.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.BorderLayout; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.JScrollPane; /** * * @author Jiri Sedlacek */ class MBeansOperationsView extends JPanel { private MBeansTab mbeansTab; public MBeansOperationsView(MBeansTab mbeansTab) { this.mbeansTab = mbeansTab; initComponents(); } private void initComponents() { setLayout(new BorderLayout()); setOpaque(false); JPanel operations = mbeansTab.getOperationsPanel(); JScrollPane operationsScrollPane = new JScrollPane(operations, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); operationsScrollPane.setViewportBorder(BorderFactory.createEmptyBorder()); add(operationsScrollPane, BorderLayout.CENTER); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansTab.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.tools.jmx.CachedMBeanServerConnection; import org.graalvm.visualvm.tools.jmx.CachedMBeanServerConnectionFactory; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import org.graalvm.visualvm.modules.mbeans.options.GlobalPreferences; import java.awt.BorderLayout; import java.awt.EventQueue; import java.beans.*; import java.io.*; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.*; import org.openide.util.RequestProcessor; class MBeansTab extends JPanel implements NotificationListener, PropertyChangeListener, TreeSelectionListener, TreeWillExpandListener { private static final Logger LOGGER = Logger.getLogger(MBeansTab.class.getName()); private static final RequestProcessor worker = new RequestProcessor("MBeansTab Processor"); // NOI18N private Application application; private DataViewComponent view; private XTree tree; private XSheet sheet; private XDataViewer viewer; private CachedMBeanServerConnection cachedMBSC; public static String getTabName() { return Resources.getText("LBL_MBeans"); // NOI18N } public MBeansTab(Application application) { this.application = application; addPropertyChangeListener(this); setupTab(); } public RequestProcessor getRequestProcessor() { return worker; } public XDataViewer getDataViewer() { return viewer; } public XTree getTree() { return tree; } public XSheet getSheet() { return sheet; } public JPanel getAttributesPanel() { return sheet.getAttributes(); } public JPanel getOperationsPanel() { return sheet.getOperations(); } public JPanel getNotificationsPanel() { return sheet.getNotifications(); } public JPanel getMetadataPanel() { return sheet.getMetadata(); } public DataViewComponent getView() { return view; } public void setView(DataViewComponent view) { this.view = view; } public JButton getButtonAt(int position) { JComponent containerPanel = (JComponent) view.getComponent(0); JComponent detailsPanel = (JComponent) containerPanel.getComponent(1); JSplitPane detailsVerticalSplitter = (JSplitPane) detailsPanel.getComponent(0); JComponent detailsTopPanel = (JComponent) detailsVerticalSplitter.getLeftComponent(); JSplitPane detailsTopHorizontalSplitter = (JSplitPane) detailsTopPanel.getComponent(0); JComponent detailsTopRightArea = (JComponent) detailsTopHorizontalSplitter.getRightComponent(); JComponent captionArea = (JComponent) detailsTopRightArea.getComponent(0); JComponent tabsContainer = (JComponent) captionArea.getComponent(0); JComponent tabButtonContainer = (JComponent) tabsContainer.getComponent(position); return (JButton) tabButtonContainer.getComponent(0); } public void dispose() { removePropertyChangeListener(this); tree.removeTreeSelectionListener(this); tree.removeTreeWillExpandListener(this); sheet.dispose(); } public int getUpdateInterval() { return GlobalPreferences.sharedInstance().getPlottersPoll() * 1000; } public void buildMBeanServerView() { SwingWorker, Void> sw = new SwingWorker, Void>() { @Override public Set doInBackground() { // Register listener for MBean registration/unregistration // try { getMBeanServerConnection().addNotificationListener( MBeanServerDelegate.DELEGATE_NAME, MBeansTab.this, null, null); } catch (InstanceNotFoundException e) { // Should never happen because the MBeanServerDelegate // is always present in any standard MBeanServer // LOGGER.throwing(MBeansTab.class.getName(), "buildMBeanServerView", e); // NOI18N } catch (IOException e) { LOGGER.throwing(MBeansTab.class.getName(), "buildMBeanServerView", e); // NOI18N return null; } // Retrieve MBeans from MBeanServer // Set mbeans = null; try { mbeans = getMBeanServerConnection().queryNames(null,null); } catch (IOException e) { LOGGER.throwing(MBeansTab.class.getName(), "buildMBeanServerView", e); // NOI18N return null; } return mbeans; } @Override protected void done() { try { // Wait for mbsc.queryNames() result Set mbeans = get(); // Do not display anything until the new tree has been built // tree.setVisible(false); // Cleanup current tree // tree.removeAll(); // Add MBeans to tree // tree.addMBeansToView(mbeans); // Display the new tree // tree.setVisible(true); } catch (Exception e) { Throwable t = Utils.getActualException(e); LOGGER.log(Level.SEVERE, "Problem at MBean tree construction", t); // NOI18N } } }; worker.post(sw); } public MBeanServerConnection getMBeanServerConnection() { JmxModel jmx = JmxModelFactory.getJmxModelFor(application); return jmx == null ? null : jmx.getMBeanServerConnection(); } public CachedMBeanServerConnection getCachedMBeanServerConnection() { if (cachedMBSC == null) { cachedMBSC = CachedMBeanServerConnectionFactory.getCachedMBeanServerConnection( getMBeanServerConnection(), getUpdateInterval()); } return cachedMBSC; } private void setupTab() { // set up the split pane with the MBean tree and MBean sheet panels setLayout(new BorderLayout()); JSplitPane mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); mainSplit.setDividerLocation(160); mainSplit.setBorder(BorderFactory.createEmptyBorder()); // set up the MBean tree panel (left pane) tree = new XTree(this); tree.setCellRenderer(new XTreeRenderer()); tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION); tree.addTreeSelectionListener(this); tree.addTreeWillExpandListener(this); JScrollPane theScrollPane = new JScrollPane( tree, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); JPanel treePanel = new JPanel(new BorderLayout()); treePanel.add(theScrollPane, BorderLayout.CENTER); mainSplit.add(treePanel, JSplitPane.LEFT, 0); // set up the MBean sheet panel (right pane) viewer = new XDataViewer(this); sheet = new XSheet(this); mainSplit.add(sheet, JSplitPane.RIGHT, 0); add(mainSplit); } /* notification listener: handleNotification */ public void handleNotification( final Notification notification, Object handback) { EventQueue.invokeLater(new Runnable() { public void run() { if (notification instanceof MBeanServerNotification) { ObjectName mbean = ((MBeanServerNotification) notification).getMBeanName(); if (notification.getType().equals( MBeanServerNotification.REGISTRATION_NOTIFICATION)) { tree.addMBeanToView(mbean); } else if (notification.getType().equals( MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { tree.removeMBeanFromView(mbean); } } } }); } /* property change listener: propertyChange */ public void propertyChange(PropertyChangeEvent evt) { if (JmxModel.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) { ConnectionState newState = (ConnectionState) evt.getNewValue(); switch (newState) { case CONNECTED: buildMBeanServerView(); break; case DISCONNECTED: dispose(); break; } } } /* tree selection listener: valueChanged */ public void valueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); sheet.displayNode(node); } /* tree will expand listener: treeWillExpand */ public void treeWillExpand(TreeExpansionEvent e) throws ExpandVetoException { // TreePath path = e.getPath(); // // if first path component has already been expanded do nothing // // else build the tree branch for the given domain // if (!tree.hasBeenExpanded(path)) { // DefaultMutableTreeNode node = // (DefaultMutableTreeNode) path.getLastPathComponent(); // // TODO: build branch for given domain - queryNames("d:*", null); // // - if not already expanded, create from scracth // // - if already expanded, update // } } /* tree will expand listener: treeWillCollapse */ public void treeWillCollapse(TreeExpansionEvent e) throws ExpandVetoException { } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansTreeView.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState; import java.awt.BorderLayout; import java.awt.Dimension; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; /** * * @author Jiri Sedlacek */ class MBeansTreeView extends JPanel implements PropertyChangeListener { private MBeansTab mbeansTab; public MBeansTreeView(MBeansTab mbeansTab) { this.mbeansTab = mbeansTab; initComponents(); } public void dispose() { removePropertyChangeListener(this); mbeansTab.getTree().clearSelection(); mbeansTab.getTree().setEnabled(false); } /* property change listener: propertyChange */ public void propertyChange(PropertyChangeEvent evt) { if (JmxModel.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) { ConnectionState newState = (ConnectionState) evt.getNewValue(); switch (newState) { case DISCONNECTED: dispose(); break; } } } private void initComponents() { setLayout(new BorderLayout()); setOpaque(false); setPreferredSize(new Dimension(220, 1)); JTree mbeansTree = mbeansTab.getTree(); mbeansTab.buildMBeanServerView(); JScrollPane mbeansTreeScrollPane = new JScrollPane(mbeansTree, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); mbeansTreeScrollPane.setViewportBorder(BorderFactory.createEmptyBorder()); add(mbeansTreeScrollPane, BorderLayout.CENTER); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansView.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JTextArea; import org.openide.util.ImageUtilities; import org.openide.util.WeakListeners; /** * * @author Jiri Sedlacek * @author Luis-Miguel Alventosa */ class MBeansView extends DataSourceView { private static final String IMAGE_PATH = "org/graalvm/visualvm/modules/mbeans/ui/resources/mbeans.png"; // NOI18N private Application application; private MBeansTab mbeansTab; private MBeansTreeView mbeansTreeView; public MBeansView(Application application) { super(application, Resources.getText("LBL_MBeans"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 50, false); // NOI18N this.application = application; } @Override protected void removed() { if (mbeansTreeView != null) { mbeansTreeView.dispose(); } if (mbeansTab != null) { mbeansTab.dispose(); } } protected DataViewComponent createComponent() { DataViewComponent dvc = null; JmxModel jmx = JmxModelFactory.getJmxModelFor(application); if (jmx == null || jmx.getConnectionState() != JmxModel.ConnectionState.CONNECTED) { JTextArea textArea = new JTextArea(); textArea.setBorder(BorderFactory.createEmptyBorder(25, 9, 9, 9)); textArea.setEditable(false); textArea.setLineWrap(true); textArea.setWrapStyleWord(true); textArea.setText(Resources.getText("LBL_ConnectionNotEstablished")); // NOI18N dvc = new DataViewComponent( new DataViewComponent.MasterView(Resources.getText("LBL_MBeansBrowser"), null, textArea), // NOI18N new DataViewComponent.MasterViewConfiguration(true)); } else { // MBeansTab mbeansTab = new MBeansTab(application); jmx.addPropertyChangeListener(WeakListeners.propertyChange(mbeansTab, jmx)); // MBeansTreeView mbeansTreeView = new MBeansTreeView(mbeansTab); jmx.addPropertyChangeListener(WeakListeners.propertyChange(mbeansTreeView, jmx)); // MBeansAttributesView MBeansAttributesView mbeansAttributesView = new MBeansAttributesView(mbeansTab); // MBeansOperationsView MBeansOperationsView mbeansOperationsView = new MBeansOperationsView(mbeansTab); // MBeansNotificationsView MBeansNotificationsView mbeansNotificationsView = new MBeansNotificationsView(mbeansTab); // MBeansMetadataView MBeansMetadataView mbeansMetadataView = new MBeansMetadataView(mbeansTab); DataViewComponent.MasterView monitoringMasterView = new DataViewComponent.MasterView(Resources.getText("LBL_MBeansBrowser"), null, new JLabel(" ")); // NOI18N DataViewComponent.MasterViewConfiguration monitoringMasterConfiguration = new DataViewComponent.MasterViewConfiguration(false); dvc = new DataViewComponent(monitoringMasterView, monitoringMasterConfiguration); dvc.configureDetailsView(new DataViewComponent.DetailsViewConfiguration(0.33, 0, -1, -1, -1, -1)); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(Resources.getText("LBL_MBeans"), false), DataViewComponent.TOP_LEFT); // NOI18N dvc.addDetailsView(new DataViewComponent.DetailsView(Resources.getText("LBL_MBeans"), null, 10, mbeansTreeView, null), DataViewComponent.TOP_LEFT); // NOI18N dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(Resources.getText("LBL_Details"), false), DataViewComponent.TOP_RIGHT); // NOI18N dvc.addDetailsView(new DataViewComponent.DetailsView(Resources.getText("LBL_Attributes"), null, 10, mbeansAttributesView, null), DataViewComponent.TOP_RIGHT); // NOI18N dvc.addDetailsView(new DataViewComponent.DetailsView(Resources.getText("LBL_Operations"), null, 20, mbeansOperationsView, null), DataViewComponent.TOP_RIGHT); // NOI18N dvc.addDetailsView(new DataViewComponent.DetailsView(Resources.getText("LBL_Notifications"), null, 30, mbeansNotificationsView, null), DataViewComponent.TOP_RIGHT); // NOI18N dvc.addDetailsView(new DataViewComponent.DetailsView(Resources.getText("LBL_Metadata"), null, 40, mbeansMetadataView, null), DataViewComponent.TOP_RIGHT); // NOI18N mbeansTab.setView(dvc); mbeansTab.getButtonAt(0).setEnabled(false); // Disable "Attributes" mbeansTab.getButtonAt(1).setEnabled(false); // Disable "Operations" mbeansTab.getButtonAt(2).setEnabled(false); // Disable "Notifications" mbeansTab.getButtonAt(3).setEnabled(false); // Disable "Metadata" } return dvc; } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansViewProvider.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.DataSourceViewProvider; import org.graalvm.visualvm.core.ui.DataSourceViewsManager; /** * * @author Jiri Sedlacek * @author Luis-Miguel Alventosa */ public class MBeansViewProvider extends DataSourceViewProvider { protected boolean supportsViewFor(Application application) { return true; } protected DataSourceView createView(Application application) { return new MBeansView(application); } public void initialize() { DataSourceViewsManager.sharedInstance().addViewProvider(this, Application.class); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansViewsSupport.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; /** * * @author Luis-Miguel Alventosa */ public final class MBeansViewsSupport { private static MBeansViewsSupport sharedInstance; public static synchronized MBeansViewsSupport sharedInstance() { if (sharedInstance == null) { sharedInstance = new MBeansViewsSupport(); } return sharedInstance; } private MBeansViewsSupport() { new MBeansViewProvider().initialize(); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/OperationEntry.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.*; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.*; import javax.swing.*; @SuppressWarnings("serial") class OperationEntry extends JPanel { private final static Logger LOGGER = Logger.getLogger(OperationEntry.class.getName()); private MBeanOperationInfo operation; private JComboBox sigs; private Dimension preferredSize; private XTextField inputs[]; public OperationEntry (MBeanOperationInfo operation, boolean isCallable, JButton button, XMBeanOperations xoperations) { super(new BorderLayout()); this.operation = operation; setLayout(new FlowLayout(FlowLayout.LEFT)); setPanel(isCallable, button, xoperations); } /** * This method chops off the throws exceptions, removes "java.lang". */ private String preProcessSignature(String signature) { int index; if ((index=signature.indexOf(" throws"))>0) { // NOI18N signature = signature.substring(0,index); } while ((index = signature.indexOf("java.lang."))>0) { // NOI18N signature = signature.substring(0,index)+ signature.substring(index+10,signature.length()); } return signature; } private void setPanel(boolean isCallable, JButton button, XMBeanOperations xoperations) { try { MBeanParameterInfo params[] = operation.getSignature(); add(new JLabel("(",JLabel.CENTER)); // NOI18N inputs = new XTextField[params.length]; for (int i = 0; i < params.length; i++) { if(params[i].getName() != null) { JLabel name = new JLabel(params[i].getName(), JLabel.CENTER); name.setToolTipText(params[i].getDescription()); add(name); } String defaultTextValue = Utils.getDefaultValue(params[i].getType()); int fieldWidth = defaultTextValue.length(); if (fieldWidth > 15) fieldWidth = 15; else if (fieldWidth < 10) fieldWidth = 10; Class clazz; try { clazz = Utils.getClass(params[i].getType()); } catch (ClassNotFoundException e) { clazz = null; } add(inputs[i] = new XTextField(Utils.getReadableClassName(defaultTextValue), clazz, fieldWidth, isCallable, button, xoperations)); inputs[i].setHorizontalAlignment(SwingConstants.CENTER); if (i < params.length-1) add(new JLabel(",",JLabel.CENTER)); // NOI18N } add(new JLabel(")",JLabel.CENTER)); // NOI18N validate(); doLayout(); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error setting Operation panel: ", e); // NOI18N } } public String[] getSignature() { MBeanParameterInfo params[] = operation.getSignature(); String result[] = new String[params.length]; for (int i = 0; i < params.length; i++) { result[i] = params[i].getType(); } return result; } public Object[] getParameters() throws Exception { MBeanParameterInfo params[] = operation.getSignature(); String signature[] = new String[params.length]; for (int i = 0; i < params.length; i++) signature[i] = params[i].getType(); return Utils.getParameters(inputs,signature); } public String getReturnType() { return operation.getReturnType(); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Plotter.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState; import java.awt.*; import java.awt.event.*; import java.beans.*; import java.io.*; import java.lang.reflect.Array; import java.util.*; import javax.accessibility.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.filechooser.*; import javax.swing.filechooser.FileFilter; import org.openide.windows.WindowManager; import static org.graalvm.visualvm.modules.mbeans.Formatter.*; import static org.graalvm.visualvm.modules.mbeans.Resources.*; import static org.graalvm.visualvm.modules.mbeans.Utilities.*; class Plotter extends JComponent implements Accessible, ActionListener, PropertyChangeListener { public static enum Unit { NONE, BYTES, PERCENT } static final String[] rangeNames = { Resources.getText("LBL_1_min"), // NOI18N Resources.getText("LBL_5_min"), // NOI18N Resources.getText("LBL_10_min"), // NOI18N Resources.getText("LBL_30_min"), // NOI18N Resources.getText("LBL_1_hour"), // NOI18N Resources.getText("LBL_2_hours"), // NOI18N Resources.getText("LBL_3_hours"), // NOI18N Resources.getText("LBL_6_hours"), // NOI18N Resources.getText("LBL_12_hours"), // NOI18N Resources.getText("LBL_1_day"), // NOI18N Resources.getText("LBL_7_days"), // NOI18N Resources.getText("LBL_1_month"), // NOI18N Resources.getText("LBL_3_months"), // NOI18N Resources.getText("LBL_6_months"), // NOI18N Resources.getText("LBL_1_year"), // NOI18N Resources.getText("LBL_All") // NOI18N }; static final int[] rangeValues = { 1, 5, 10, 30, 1 * 60, 2 * 60, 3 * 60, 6 * 60, 12 * 60, 1 * 24 * 60, 7 * 24 * 60, 1 * 31 * 24 * 60, 3 * 31 * 24 * 60, 6 * 31 * 24 * 60, 366 * 24 * 60, -1 }; final static long SECOND = 1000; final static long MINUTE = 60 * SECOND; final static long HOUR = 60 * MINUTE; final static long DAY = 24 * HOUR; final static Color bgColor = new Color(250, 250, 250); final static Color defaultColor = Color.blue.darker(); final static int ARRAY_SIZE_INCREMENT = 4000; private static Stroke dashedStroke; private TimeStamps times = new TimeStamps(); private ArrayList seqs = new ArrayList(); private JPopupMenu popupMenu; private JMenu timeRangeMenu; private JRadioButtonMenuItem[] menuRBs; private JMenuItem saveAsMI; private JFileChooser saveFC; private int viewRange = -1; // Minutes (value <= 0 means full range) private Unit unit; private int decimals; private double decimalsMultiplier; private Border border = null; private Rectangle r = new Rectangle(1, 1, 1, 1); private Font smallFont = null; // Initial margins, may be recalculated as needed private int topMargin = 10; private int bottomMargin = 45; private int leftMargin = 65; private int rightMargin = 70; // if display legend is true, the name of the attribute is displayed // next to the attribute value on the right of the plotter... private final boolean displayLegend; public Plotter() { this(Unit.NONE, 0, true); } public Plotter(Unit unit) { this(unit, 0, true); } public Plotter(Unit unit, int decimals) { this(unit, decimals, true); } // Note: If decimals > 0 then values must be decimally shifted left // that many places, i.e. multiplied by Math.pow(10.0, decimals). public Plotter(Unit unit, int decimals, boolean displayLegend) { this.displayLegend = displayLegend; setUnit(unit); setDecimals(decimals); enableEvents(AWTEvent.MOUSE_EVENT_MASK); addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if (getParent() instanceof PlotterPanel) { getParent().requestFocusInWindow(); } } }); } public void setUnit(Unit unit) { this.unit = unit; } public void setDecimals(int decimals) { this.decimals = decimals; this.decimalsMultiplier = Math.pow(10.0, decimals); } public void createSequence(String key, String name, Color color, boolean isPlotted) { Sequence seq = getSequence(key); if (seq == null) { seq = new Sequence(key); } seq.name = name; seq.color = (color != null) ? color : defaultColor; seq.isPlotted = isPlotted; seqs.add(seq); } public void setUseDashedTransitions(String key, boolean b) { Sequence seq = getSequence(key); if (seq != null) { seq.transitionStroke = b ? getDashedStroke() : null; } } public void setIsPlotted(String key, boolean isPlotted) { Sequence seq = getSequence(key); if (seq != null) { seq.isPlotted = isPlotted; } } // Note: If decimals > 0 then values must be decimally shifted left // that many places, i.e. multiplied by Math.pow(10.0, decimals). public synchronized void addValues(long time, long... values) { assert (values.length == seqs.size()); times.add(time); for (int i = 0; i < values.length; i++) { seqs.get(i).add(values[i]); } repaint(); } private Sequence getSequence(String key) { for (Sequence seq : seqs) { if (seq.key.equals(key)) { return seq; } } return null; } /** * @return the displayed time range in minutes, or -1 for all data */ public int getViewRange() { return viewRange; } /** * @param minutes the displayed time range in minutes, or -1 to diaplay all data */ public void setViewRange(int minutes) { if (minutes != viewRange) { int oldValue = viewRange; viewRange = minutes; /* Do not i18n this string */ firePropertyChange("viewRange", oldValue, viewRange); // NOI18N if (popupMenu != null) { for (int i = 0; i < menuRBs.length; i++) { if (rangeValues[i] == viewRange) { menuRBs[i].setSelected(true); break; } } } repaint(); } } @Override public JPopupMenu getComponentPopupMenu() { if (popupMenu == null) { popupMenu = new JPopupMenu(Resources.getText("LBL_Chart") + ":"); // NOI18N timeRangeMenu = new JMenu(Resources.getText("LBL_Plotter.timeRangeMenu")); // NOI18N timeRangeMenu.setMnemonic(getMnemonicInt("LBL_Plotter.timeRangeMenu")); // NOI18N popupMenu.add(timeRangeMenu); menuRBs = new JRadioButtonMenuItem[rangeNames.length]; ButtonGroup rbGroup = new ButtonGroup(); for (int i = 0; i < rangeNames.length; i++) { menuRBs[i] = new JRadioButtonMenuItem(rangeNames[i]); rbGroup.add(menuRBs[i]); menuRBs[i].addActionListener(this); if (viewRange == rangeValues[i]) { menuRBs[i].setSelected(true); } timeRangeMenu.add(menuRBs[i]); } popupMenu.addSeparator(); saveAsMI = new JMenuItem(getText("LBL_Plotter.saveAsMenuItem")); // NOI18N saveAsMI.setMnemonic(getMnemonicInt("LBL_Plotter.saveAsMenuItem")); // NOI18N saveAsMI.addActionListener(this); popupMenu.add(saveAsMI); } return popupMenu; } public void actionPerformed(ActionEvent ev) { JComponent src = (JComponent)ev.getSource(); if (src == saveAsMI) { saveAs(); } else { int index = timeRangeMenu.getPopupMenu().getComponentIndex(src); setViewRange(rangeValues[index]); } } private void saveAs() { if (saveFC == null) { saveFC = new SaveDataFileChooser(); } int ret = saveFC.showSaveDialog(WindowManager.getDefault().getMainWindow()); if (ret == JFileChooser.APPROVE_OPTION) { saveDataToFile(saveFC.getSelectedFile()); } } private void saveDataToFile(File file) { try { PrintStream out = new PrintStream(new FileOutputStream(file)); // Print header line out.print("Time"); // NOI18N for (Sequence seq : seqs) { out.print(","+seq.name); // NOI18N } out.println(); // Print data lines if (seqs.size() > 0 && seqs.get(0).size > 0) { for (int i = 0; i < seqs.get(0).size; i++) { double excelTime = toExcelTime(times.time(i)); out.print(String.format(Locale.ENGLISH, "%.6f", excelTime)); // NOI18N for (Sequence seq : seqs) { out.print("," + getFormattedValue(seq.value(i), false)); // NOI18N } out.println(); } } out.close(); JOptionPane.showMessageDialog(this, getText("LBL_FileChooser.savedFile", // NOI18N file.getAbsolutePath(), file.length())); } catch (IOException ex) { String msg = ex.getLocalizedMessage(); String path = file.getAbsolutePath(); if (msg.startsWith(path)) { msg = msg.substring(path.length()).trim(); } JOptionPane.showMessageDialog(this, getText("LBL_FileChooser.saveFailed.message", // NOI18N path, msg), getText("LBL_FileChooser.saveFailed.title"), // NOI18N JOptionPane.ERROR_MESSAGE); } } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Color oldColor = g.getColor(); Font oldFont = g.getFont(); Color fg = getForeground(); Color bg = getBackground(); boolean bgIsLight = (bg.getRed() > 200 && bg.getGreen() > 200 && bg.getBlue() > 200); ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (smallFont == null) { smallFont = oldFont.deriveFont(9.0F); } r.x = leftMargin - 5; r.y = topMargin - 8; r.width = getWidth()-leftMargin-rightMargin; r.height = getHeight()-topMargin-bottomMargin+16; if (border == null) { // By setting colors here, we avoid recalculating them // over and over. border = new BevelBorder(BevelBorder.LOWERED, getBackground().brighter().brighter(), getBackground().brighter(), getBackground().darker().darker(), getBackground().darker()); } border.paintBorder(this, g, r.x, r.y, r.width, r.height); // Fill background color g.setColor(bgColor); g.fillRect(r.x+2, r.y+2, r.width-4, r.height-4); g.setColor(oldColor); long tMin = Long.MAX_VALUE; long tMax = Long.MIN_VALUE; long vMin = Long.MAX_VALUE; long vMax = 1; int w = getWidth()-rightMargin-leftMargin-10; int h = getHeight()-topMargin-bottomMargin; if (times.size > 1) { tMin = Math.min(tMin, times.time(0)); tMax = Math.max(tMax, times.time(times.size-1)); } long viewRangeMS; if (viewRange > 0) { viewRangeMS = viewRange * MINUTE; } else { // Display full time range, but no less than a minute viewRangeMS = Math.max(tMax - tMin, 1 * MINUTE); } // Calculate min/max values for (Sequence seq : seqs) { if (seq.size > 0) { for (int i = 0; i < seq.size; i++) { if (seq.size == 1 || times.time(i) >= tMax - viewRangeMS) { long val = seq.value(i); if (val > Long.MIN_VALUE) { vMax = Math.max(vMax, val); vMin = Math.min(vMin, val); } } } } else { vMin = 0L; } if (unit == Unit.BYTES || !seq.isPlotted) { // We'll scale only to the first (main) value set. // TODO: Use a separate property for this. break; } } // Normalize scale vMax = normalizeMax(vMax); if (vMin > 0) { if (vMax / vMin > 4) { vMin = 0; } else { vMin = normalizeMin(vMin); } } g.setColor(fg); // Axes // Draw vertical axis int x = leftMargin - 18; int y = topMargin; FontMetrics fm = g.getFontMetrics(); g.drawLine(x, y, x, y+h); int n = 5; if ((""+vMax).startsWith("2")) { // NOI18N n = 4; } else if ((""+vMax).startsWith("3")) { // NOI18N n = 6; } else if ((""+vMax).startsWith("4")) { // NOI18N n = 4; } else if ((""+vMax).startsWith("6")) { // NOI18N n = 6; } else if ((""+vMax).startsWith("7")) { // NOI18N n = 7; } else if ((""+vMax).startsWith("8")) { // NOI18N n = 8; } else if ((""+vMax).startsWith("9")) { // NOI18N n = 3; } // Ticks ArrayList tickValues = new ArrayList(); tickValues.add(vMin); for (int i = 0; i < n; i++) { long v = i * vMax / n; if (v > vMin) { tickValues.add(v); } } tickValues.add(vMax); n = tickValues.size(); String[] tickStrings = new String[n]; for (int i = 0; i < n; i++) { long v = tickValues.get(i); tickStrings[i] = getSizeString(v, vMax); } // Trim trailing decimal zeroes. if (decimals > 0) { boolean trimLast = true; boolean removedDecimalPoint = false; do { for (String str : tickStrings) { if (!(str.endsWith("0") || str.endsWith("."))) { // NOI18N trimLast = false; break; } } if (trimLast) { if (tickStrings[0].endsWith(".")) { // NOI18N removedDecimalPoint = true; } for (int i = 0; i < n; i++) { String str = tickStrings[i]; tickStrings[i] = str.substring(0, str.length()-1); } } } while (trimLast && !removedDecimalPoint); } // Draw ticks int lastY = Integer.MAX_VALUE; for (int i = 0; i < n; i++) { long v = tickValues.get(i); y = topMargin+h-(int)(h * (v-vMin) / (vMax-vMin)); g.drawLine(x-2, y, x+2, y); String s = tickStrings[i]; if (unit == Unit.PERCENT) { s += "%"; // NOI18N } int sx = x-6-fm.stringWidth(s); if (y < lastY-13) { if (checkLeftMargin(sx)) { // Wait for next repaint return; } g.drawString(s, sx, y+4); } // Draw horizontal grid line g.setColor(Color.lightGray); g.drawLine(r.x + 4, y, r.x + r.width - 4, y); g.setColor(fg); lastY = y; } // Draw horizontal axis x = leftMargin; y = topMargin + h + 15; g.drawLine(x, y, x+w, y); long t1 = tMax; if (t1 <= 0L) { // No data yet, so draw current time t1 = System.currentTimeMillis(); } long tz = timeDF.getTimeZone().getOffset(t1); long tickInterval = calculateTickInterval(w, 40, viewRangeMS); if (tickInterval > 3 * HOUR) { tickInterval = calculateTickInterval(w, 80, viewRangeMS); } long t0 = tickInterval - (t1 - viewRangeMS + tz) % tickInterval; while (t0 < viewRangeMS) { x = leftMargin + (int)(w * t0 / viewRangeMS); g.drawLine(x, y-2, x, y+2); long t = t1 - viewRangeMS + t0; String str = formatClockTime(t); g.drawString(str, x, y+16); //if (tickInterval > (1 * HOUR) && t % (1 * DAY) == 0) { if ((t + tz) % (1 * DAY) == 0) { str = formatDate(t); g.drawString(str, x, y+27); } // Draw vertical grid line g.setColor(Color.lightGray); g.drawLine(x, topMargin, x, topMargin + h); g.setColor(fg); t0 += tickInterval; } // Plot values int start = 0; int nValues = 0; int nLists = seqs.size(); if (nLists > 0) { nValues = seqs.get(0).size; } if (nValues == 0) { g.setColor(oldColor); return; } else { Sequence seq = seqs.get(0); // Find starting point for (int p = 0; p < seq.size; p++) { if (times.time(p) >= tMax - viewRangeMS) { start = p; break; } } } //Optimization: collapse plot of more than four values per pixel int pointsPerPixel = (nValues - start) / w; if (pointsPerPixel < 4) { pointsPerPixel = 1; } // Draw graphs // Loop backwards over sequences because the first needs to be painted on top for (int i = nLists-1; i >= 0; i--) { int x0 = leftMargin; int y0 = topMargin + h + 1; Sequence seq = seqs.get(i); if (seq.isPlotted && seq.size > 0) { // Paint twice, with white and with color for (int pass = 0; pass < 2; pass++) { g.setColor((pass == 0) ? Color.white : seq.color); int x1 = -1; long v1 = -1; for (int p = start; p < nValues; p += pointsPerPixel) { // Make sure we get the last value if (pointsPerPixel > 1 && p >= nValues - pointsPerPixel) { p = nValues - 1; } int x2 = (int)(w * (times.time(p)-(t1-viewRangeMS)) / viewRangeMS); long v2 = seq.value(p); if (v2 >= vMin && v2 <= vMax) { int y2 = (int)(h * (v2 -vMin) / (vMax-vMin)); if (x1 >= 0 && v1 >= vMin && v1 <= vMax) { int y1 = (int)(h * (v1-vMin) / (vMax-vMin)); if (y1 == y2) { // fillrect is much faster g.fillRect(x0+x1, y0-y1-pass, x2-x1, 1); } else { Graphics2D g2d = (Graphics2D)g; Stroke oldStroke = null; if (seq.transitionStroke != null) { oldStroke = g2d.getStroke(); g2d.setStroke(seq.transitionStroke); } g.drawLine(x0+x1, y0-y1-pass, x0+x2, y0-y2-pass); if (oldStroke != null) { g2d.setStroke(oldStroke); } } } } x1 = x2; v1 = v2; } } // Current value long v = seq.value(seq.size - 1); if (v >= vMin && v <= vMax) { if (bgIsLight) { g.setColor(seq.color); } else { g.setColor(fg); } x = r.x + r.width + 2; y = topMargin+h-(int)(h * (v-vMin) / (vMax-vMin)); // a small triangle/arrow g.fillPolygon(new int[] { x+2, x+6, x+6 }, new int[] { y, y+3, y-3 }, 3); } g.setColor(fg); } } int[] valueStringSlots = new int[nLists]; for (int i = 0; i < nLists; i++) valueStringSlots[i] = -1; for (int i = 0; i < nLists; i++) { Sequence seq = seqs.get(i); if (seq.isPlotted && seq.size > 0) { // Draw current value // TODO: collapse values if pointsPerPixel >= 4 long v = seq.value(seq.size - 1); if (v >= vMin && v <= vMax) { x = r.x + r.width + 2; y = topMargin+h-(int)(h * (v-vMin) / (vMax-vMin)); int y2 = getValueStringSlot(valueStringSlots, y, 2*10, i); g.setFont(smallFont); if (bgIsLight) { g.setColor(seq.color); } else { g.setColor(fg); } String curValue = getFormattedValue(v, true); if (unit == Unit.PERCENT) { curValue += "%"; // NOI18N } int valWidth = fm.stringWidth(curValue); String legend = displayLegend?seq.name:""; int legendWidth = fm.stringWidth(legend); if (checkRightMargin(valWidth) || checkRightMargin(legendWidth)) { // Wait for next repaint return; } g.drawString(legend , x + 17, Math.min(topMargin+h, y2 + 3 - 10)); g.drawString(curValue, x + 17, Math.min(topMargin+h + 10, y2 + 3)); // Maybe draw a short line to value if (y2 > y + 3) { g.drawLine(x + 9, y + 2, x + 14, y2); } else if (y2 < y - 3) { g.drawLine(x + 9, y - 2, x + 14, y2); } } g.setFont(oldFont); g.setColor(fg); } } g.setColor(oldColor); } private boolean checkLeftMargin(int x) { // Make sure leftMargin has at least 2 pixels over if (x < 2) { leftMargin += (2 - x); // Repaint from top (above any cell renderers) SwingUtilities.getWindowAncestor(this).repaint(); return true; } return false; } private boolean checkRightMargin(int w) { // Make sure rightMargin has at least 2 pixels over if (w + 2 > rightMargin) { rightMargin = (w + 2); // Repaint from top (above any cell renderers) SwingUtilities.getWindowAncestor(this).repaint(); return true; } return false; } private int getValueStringSlot(int[] slots, int y, int h, int i) { for (int s = 0; s < slots.length; s++) { if (slots[s] >= y && slots[s] < y + h) { // collide below us if (slots[s] > h) { return getValueStringSlot(slots, slots[s]-h, h, i); } else { return getValueStringSlot(slots, slots[s]+h, h, i); } } else if (y >= h && slots[s] > y - h && slots[s] < y) { // collide above us return getValueStringSlot(slots, slots[s]+h, h, i); } } slots[i] = y; return y; } private long calculateTickInterval(int w, int hGap, long viewRangeMS) { long tickInterval = viewRangeMS * hGap / w; if (tickInterval < 1 * MINUTE) { tickInterval = 1 * MINUTE; } else if (tickInterval < 5 * MINUTE) { tickInterval = 5 * MINUTE; } else if (tickInterval < 10 * MINUTE) { tickInterval = 10 * MINUTE; } else if (tickInterval < 30 * MINUTE) { tickInterval = 30 * MINUTE; } else if (tickInterval < 1 * HOUR) { tickInterval = 1 * HOUR; } else if (tickInterval < 3 * HOUR) { tickInterval = 3 * HOUR; } else if (tickInterval < 6 * HOUR) { tickInterval = 6 * HOUR; } else if (tickInterval < 12 * HOUR) { tickInterval = 12 * HOUR; } else if (tickInterval < 1 * DAY) { tickInterval = 1 * DAY; } else { tickInterval = normalizeMax(tickInterval / DAY) * DAY; } return tickInterval; } private long normalizeMin(long l) { int exp = (int)Math.log10((double)l); long multiple = (long)Math.pow(10.0, exp); int i = (int)(l / multiple); return i * multiple; } private long normalizeMax(long l) { int exp = (int)Math.log10((double)l); long multiple = (long)Math.pow(10.0, exp); int i = (int)(l / multiple); l = (i+1)*multiple; return l; } private String getFormattedValue(long v, boolean groupDigits) { String str; String fmt = "%"; // NOI18N if (groupDigits) { fmt += ","; // NOI18N } if (decimals > 0) { fmt += "." + decimals + "f"; // NOI18N str = String.format(fmt, v / decimalsMultiplier); } else { fmt += "d"; // NOI18N str = String.format(fmt, v); } return str; } private String getSizeString(long v, long vMax) { String s; if (unit == Unit.BYTES && decimals == 0) { s = formatBytes(v, vMax); } else { s = getFormattedValue(v, true); } return s; } private static synchronized Stroke getDashedStroke() { if (dashedStroke == null) { dashedStroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] { 2.0f, 3.0f }, 0.0f); } return dashedStroke; } private static Object extendArray(Object a1) { int n = Array.getLength(a1); Object a2 = Array.newInstance(a1.getClass().getComponentType(), n + ARRAY_SIZE_INCREMENT); System.arraycopy(a1, 0, a2, 0, n); return a2; } private static class TimeStamps { // Time stamps (long) are split into offsets (long) and a // series of times from the offsets (int). A new offset is // stored when the the time value doesn't fit in an int // (approx every 24 days). An array of indices is used to // define the starting point for each offset in the times // array. long[] offsets = new long[0]; int[] indices = new int[0]; int[] rtimes = new int[ARRAY_SIZE_INCREMENT]; // Number of stored timestamps int size = 0; /** * Returns the time stamp for index i */ public long time(int i) { long offset = 0; for (int j = indices.length - 1; j >= 0; j--) { if (i >= indices[j]) { offset = offsets[j]; break; } } return offset + rtimes[i]; } public void add(long time) { // May need to store a new time offset int n = offsets.length; if (n == 0 || time - offsets[n - 1] > Integer.MAX_VALUE) { // Grow offset and indices arrays and store new offset offsets = Arrays.copyOf(offsets, n + 1); offsets[n] = time; indices = Arrays.copyOf(indices, n + 1); indices[n] = size; } // May need to extend the array size if (rtimes.length == size) { rtimes = (int[])extendArray(rtimes); } // Store the time rtimes[size] = (int)(time - offsets[offsets.length - 1]); size++; } } private static class Sequence { String key; String name; Color color; boolean isPlotted; Stroke transitionStroke = null; // Values are stored in an int[] if all values will fit, // otherwise in a long[]. An int can represent up to 2 GB. // Use a random start size, so all arrays won't need to // be grown during the same update interval Object values = new byte[ARRAY_SIZE_INCREMENT + (int)(Math.random() * 100)]; // Number of stored values int size = 0; public Sequence(String key) { this.key = key; } /** * Returns the value at index i */ public long value(int i) { return Array.getLong(values, i); } public void add(long value) { // May need to switch to a larger array type if ((values instanceof byte[] || values instanceof short[] || values instanceof int[]) && value > Integer.MAX_VALUE) { long[] la = new long[Array.getLength(values)]; for (int i = 0; i < size; i++) { la[i] = Array.getLong(values, i); } values = la; } else if ((values instanceof byte[] || values instanceof short[]) && value > Short.MAX_VALUE) { int[] ia = new int[Array.getLength(values)]; for (int i = 0; i < size; i++) { ia[i] = Array.getInt(values, i); } values = ia; } else if (values instanceof byte[] && value > Byte.MAX_VALUE) { short[] sa = new short[Array.getLength(values)]; for (int i = 0; i < size; i++) { sa[i] = Array.getShort(values, i); } values = sa; } // May need to extend the array size if (Array.getLength(values) == size) { values = extendArray(values); } // Store the value if (values instanceof long[]) { ((long[])values)[size] = value; } else if (values instanceof int[]) { ((int[])values)[size] = (int)value; } else if (values instanceof short[]) { ((short[])values)[size] = (short)value; } else { ((byte[])values)[size] = (byte)value; } size++; } } // Can be overridden by subclasses long getValue() { return 0; } long getLastTimeStamp() { return times.time(times.size - 1); } long getLastValue(String key) { Sequence seq = getSequence(key); return (seq != null && seq.size > 0) ? seq.value(seq.size - 1) : 0L; } // Called on EDT public void propertyChange(PropertyChangeEvent ev) { if (JmxModel.CONNECTION_STATE_PROPERTY.equals(ev.getPropertyName())) { ConnectionState newState = (ConnectionState) ev.getNewValue(); switch (newState) { case DISCONNECTED: synchronized (this) { long time = System.currentTimeMillis(); times.add(time); for (Sequence seq : seqs) { seq.add(Long.MIN_VALUE); } } break; } } } private static class SaveDataFileChooser extends JFileChooser { SaveDataFileChooser() { setFileFilter(new FileNameExtensionFilter("CSV file", "csv")); // NOI18N } @Override public void approveSelection() { File file = getSelectedFile(); if (file != null) { FileFilter filter = getFileFilter(); if (filter != null && filter instanceof FileNameExtensionFilter) { String[] extensions = ((FileNameExtensionFilter)filter).getExtensions(); boolean goodExt = false; for (String ext : extensions) { if (file.getName().toLowerCase().endsWith("." + ext.toLowerCase())) { // NOI18N goodExt = true; break; } } if (!goodExt) { file = new File(file.getParent(), file.getName() + "." + extensions[0]); // NOI18N } } if (file.exists()) { String okStr = getText("LBL_FileChooser.fileExists.okOption"); // NOI18N String cancelStr = getText("LBL_FileChooser.fileExists.cancelOption"); // NOI18N int ret = JOptionPane.showOptionDialog(this, getText("LBL_FileChooser.fileExists.message", // NOI18N file.getName()), getText("LBL_FileChooser.fileExists.title"), // NOI18N JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, new Object[] { okStr, cancelStr }, okStr); if (ret != JOptionPane.OK_OPTION) { return; } } setSelectedFile(file); } super.approveSelection(); } } @Override public AccessibleContext getAccessibleContext() { if (accessibleContext == null) { accessibleContext = new AccessiblePlotter(); } return accessibleContext; } protected class AccessiblePlotter extends AccessibleJComponent { protected AccessiblePlotter() { setAccessibleName(getText("LBL_Plotter.accessibleName")); // NOI18N } @Override public String getAccessibleName() { String name = super.getAccessibleName(); if (seqs.size() > 0 && seqs.get(0).size > 0) { String keyValueList = ""; // NOI18N for (Sequence seq : seqs) { if (seq.isPlotted) { String value = "null"; // NOI18N if (seq.size > 0) { if (unit == Unit.BYTES) { value = getText("LBL_SizeBytes", seq.value(seq.size - 1)); // NOI18N } else { value = getFormattedValue(seq.value(seq.size - 1), false) + ((unit == Unit.PERCENT) ? "%" : ""); // NOI18N } } // Assume format string ends with newline keyValueList += getText("LBL_Plotter.accessibleName.keyAndValue", // NOI18N seq.key, value); } } name += "\n" + keyValueList + "."; // NOI18N } else { name += "\n" + getText("LBL_Plotter.accessibleName.noData"); // NOI18N } return name; } @Override public AccessibleRole getAccessibleRole() { return AccessibleRole.CANVAS; } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/PlotterPanel.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.*; import java.awt.event.*; import javax.accessibility.*; import javax.swing.*; @SuppressWarnings("serial") class PlotterPanel extends BorderedComponent { private Plotter plotter; public PlotterPanel(String labelStr, Plotter.Unit unit, boolean collapsible) { super(labelStr, new Plotter(unit), collapsible); this.plotter = (Plotter)comp; init(); } public PlotterPanel(String labelStr) { super(labelStr, null); init(); } public Plotter getPlotter() { return this.plotter; } public void setPlotter(Plotter plotter) { this.plotter = plotter; setComponent(plotter); } private void init() { setFocusable(true); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { requestFocusInWindow(); } }); } public JPopupMenu getComponentPopupMenu() { return (getPlotter() != null)? getPlotter().getComponentPopupMenu() : null; } public AccessibleContext getAccessibleContext() { if (accessibleContext == null) { accessibleContext = new AccessiblePlotterPanel(); } return accessibleContext; } protected class AccessiblePlotterPanel extends AccessibleJComponent { public String getAccessibleName() { String name = null; if (getPlotter() != null) { name = getPlotter().getAccessibleContext().getAccessibleName(); } if (name == null) { name = super.getAccessibleName(); } return name; } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Resources.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import org.openide.util.NbBundle; /** * Provides resource support for the containing java package. */ final class Resources { private Resources() { throw new AssertionError(); } /** * Returns the text of the resource for the specified * key formatted with the specified arguments. */ public static String getText(String key, Object... args) { return NbBundle.getMessage(Resources.class, key, args); } /** * Returns the mnemonic keycode int of the resource for * the specified key. */ public static int getMnemonicInt(String key) { String m = getText(key + ".mnemonic"); // NOI18N int mnemonic = m.charAt(0); if (mnemonic >= 'a' && mnemonic <= 'z') { mnemonic -= ('a' - 'A'); } return mnemonic; } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/TableSorter.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.util.*; import java.awt.event.*; import javax.swing.table.*; import javax.swing.event.*; // Imports for picking up mouse events from the JTable. import java.awt.event.MouseEvent; import javax.swing.JTable; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumnModel; @SuppressWarnings("serial") class TableSorter extends DefaultTableModel implements MouseListener { private boolean ascending = true; private TableColumnModel columnModel; private JTable tableView; private Vector evtListenerList; private int sortColumn = 0; private int[] invertedIndex; public TableSorter() { super(); evtListenerList = new Vector(); } public TableSorter(Object[] columnNames, int numRows) { super(columnNames,numRows); evtListenerList = new Vector(); } @Override public void newDataAvailable(TableModelEvent e) { super.newDataAvailable(e); invertedIndex = new int[getRowCount()]; for (int i = 0; i < invertedIndex.length; i++) { invertedIndex[i] = i; } sort(this.sortColumn, this.ascending); } @Override public void addTableModelListener(TableModelListener l) { evtListenerList.add(l); super.addTableModelListener(l); } @Override public void removeTableModelListener(TableModelListener l) { evtListenerList.remove(l); super.removeTableModelListener(l); } private void removeListeners() { for(TableModelListener tnl : evtListenerList) super.removeTableModelListener(tnl); } private void restoreListeners() { for(TableModelListener tnl : evtListenerList) super.addTableModelListener(tnl); } @SuppressWarnings("unchecked") private int compare(Object o1, Object o2) { // take care of the case where both o1 & o2 are null. Needed to keep // the method symetric. Without this quickSort gives surprising results. if (o1 == o2) return 0; if (o1==null) return 1; if (o2==null) return -1; //two object of the same class and that are comparable else if ((o1.getClass().equals(o2.getClass())) && (o1 instanceof Comparable)) { return (((Comparable) o1).compareTo(o2)); } else { return o1.toString().compareTo(o2.toString()); } } private void sort(int column, boolean isAscending) { final XMBeanAttributes attrs = (tableView instanceof XMBeanAttributes) ?(XMBeanAttributes) tableView :null; // We cannot sort rows when a cell is being // edited - so we're going to cancel cell editing here if needed. // This might happen when the user is editing a row, and clicks on // another row without validating. In that case there are two events // that compete: one is the validation of the value that was previously // edited, the other is the mouse click that opens the new editor. // // When we reach here the previous value is already validated, and the // old editor is closed, but the new editor might have opened. // It's this new editor that wil be cancelled here, if needed. // if (attrs != null && attrs.isEditing()) attrs.cancelCellEditing(); // remove registered listeners removeListeners(); // do the sort quickSort(0,getRowCount()-1,column,isAscending); // restore registered listeners restoreListeners(); // update row heights in XMBeanAttributes (required by expandable cells) if (attrs != null) { for (int i = 0; i < getRowCount(); i++) { Vector data = (Vector) dataVector.elementAt(i); attrs.updateRowHeight(data.elementAt(1), i); } } } private boolean compareS(Object s1, Object s2, boolean isAscending) { if (isAscending) return (compare(s1,s2) > 0); else return (compare(s1,s2) < 0); } private boolean compareG(Object s1, Object s2, boolean isAscending) { if (isAscending) return (compare(s1,s2) < 0); else return (compare(s1,s2) > 0); } private void quickSort(int lo0,int hi0, int key, boolean isAscending) { int lo = lo0; int hi = hi0; Object mid; if ( hi0 > lo0) { mid = getValueAt( ( lo0 + hi0 ) / 2 , key); while( lo <= hi ) { /* find the first element that is greater than * or equal to the partition element starting * from the left Index. */ while( ( lo < hi0 ) && ( compareS(mid,getValueAt(lo,key), isAscending) )) ++lo; /* find an element that is smaller than or equal to * the partition element starting from the right Index. */ while( ( hi > lo0 ) && ( compareG(mid,getValueAt(hi,key), isAscending) )) --hi; // if the indexes have not crossed, swap if( lo <= hi ) { swap(lo, hi, key); ++lo; --hi; } } /* If the right index has not reached the * left side of array * must now sort the left partition. */ if( lo0 < hi ) quickSort(lo0, hi , key, isAscending); /* If the left index has not reached the right * side of array * must now sort the right partition. */ if( lo <= hi0 ) quickSort(lo, hi0 , key, isAscending); } } private Vector getRow(int row) { return (Vector) dataVector.elementAt(row); } @SuppressWarnings("unchecked") private void setRow(Vector data, int row) { dataVector.setElementAt(data,row); } private void swap(int i, int j, int column) { Vector data = getRow(i); setRow(getRow(j),i); setRow(data,j); int a = invertedIndex[i]; invertedIndex[i] = invertedIndex[j]; invertedIndex[j] = a; } public void sortByColumn(int column) { sortByColumn(column, !ascending); } public void sortByColumn(int column, boolean ascending) { this.ascending = ascending; this.sortColumn = column; sort(column,ascending); } public int getIndexOfRow(int row) { return invertedIndex[row]; } // Add a mouse listener to the Table to trigger a table sort // when a column heading is clicked in the JTable. public void addMouseListenerToHeaderInTable(JTable table) { tableView = table; columnModel = tableView.getColumnModel(); JTableHeader th = tableView.getTableHeader(); th.addMouseListener(this); } public void mouseClicked(MouseEvent e) { int viewColumn = columnModel.getColumnIndexAtX(e.getX()); int column = tableView.convertColumnIndexToModel(viewColumn); if (e.getClickCount() == 1 && column != -1) { if (tableView instanceof XTable) { XTable attrs = (XTable) tableView; // inform the table view that the rows are going to be sorted // against the values in a given column. This gives the // chance to the table view to close its editor - if needed. // attrs.sortRequested(column); } tableView.invalidate(); sortByColumn(column); tableView.validate(); tableView.repaint(); } } public void mousePressed(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/ThreadDialog.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.*; import javax.swing.*; import java.io.*; class ThreadDialog implements Runnable { Component parentComponent; Object message; String title; int messageType; public ThreadDialog(Component parentComponent, Object message, String title, int messageType) { this.parentComponent = parentComponent; this.message = message; this.title = title; this.messageType = messageType; } public void run() { JOptionPane pane = new JOptionPane(message, messageType); JDialog dialog = pane.createDialog(parentComponent, title); dialog.setResizable(true); dialog.setVisible(true); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Utilities.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.*; import javax.accessibility.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.tree.*; import static java.lang.Math.*; /** * Miscellaneous utility methods for JConsole */ class Utilities { private static final String windowsLaF = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; // NOI18N public static void updateTransparency(JComponent comp) { LookAndFeel laf = UIManager.getLookAndFeel(); boolean transparent = laf.getClass().getName().equals(windowsLaF); setTabbedPaneTransparency(comp, transparent); } private static void setTabbedPaneTransparency(JComponent comp, boolean transparent) { for (Component child : comp.getComponents()) { if (comp instanceof JTabbedPane) { setTransparency((JComponent)child, transparent); } else if (child instanceof JComponent) { setTabbedPaneTransparency((JComponent)child, transparent); } } } private static void setTransparency(JComponent comp, boolean transparent) { comp.setOpaque(!transparent); for (Component child : comp.getComponents()) { if (child instanceof JPanel || child instanceof JSplitPane || child instanceof JScrollPane || child instanceof JViewport || child instanceof JCheckBox) { setTransparency((JComponent)child, transparent); } if (child instanceof XTree) { XTree t = (XTree)child; DefaultTreeCellRenderer cr = (DefaultTreeCellRenderer)t.getCellRenderer(); cr.setBackground(null); cr.setBackgroundNonSelectionColor(new Color(0, 0, 0, 1)); t.setCellRenderer(cr); setTransparency((JComponent)child, transparent); } } } /** * A slightly modified border for JScrollPane to be used with a JTable inside * a JTabbedPane. It has only top part and the rest is clipped to make the * overall border less thick. * The top border helps differentiating the containing table from its container. */ public static JScrollPane newTableScrollPane(JComponent comp) { return new TableScrollPane(comp); } @SuppressWarnings("serial") private static class TableScrollPane extends JScrollPane { public TableScrollPane(JComponent comp) { super(comp); } @Override protected void paintBorder(Graphics g) { Border border = getBorder(); if (border != null) { Insets insets = border.getBorderInsets(this); if (insets != null) { Shape oldClip = g.getClip(); g.clipRect(0, 0, getWidth(), insets.top); super.paintBorder(g); g.setClip(oldClip); } } } } public static void setAccessibleName(Accessible comp, String name) { comp.getAccessibleContext().setAccessibleName(name); } public static void setAccessibleDescription(Accessible comp, String description) { comp.getAccessibleContext().setAccessibleDescription(description); } /** * Modifies color c1 to ensure it has acceptable contrast * relative to color c2. * * http://www.w3.org/TR/AERT#color-contrast * http://www.cs.rit.edu/~ncs/color/t_convert.html#RGB%20to%20YIQ%20&%20YIQ%20to%20RGB */ public static Color ensureContrast(Color c1, Color c2) { double y1 = getColorBrightness(c1); double y2 = getColorBrightness(c2); if (abs(y1 - y2) < 125.0) { if (y2 < 128.0) { c1 = setColorBrightness(c1, y2 + 125.0); } else { c1 = setColorBrightness(c1, y2 - 125.0); } } return c1; } public static double getColorBrightness(Color c) { // Convert RGB -> YIQ and return the Y value return (c.getRed() * 0.299 + c.getGreen() * 0.587 + c.getBlue() * 0.114); } private static Color setColorBrightness(Color c, double y) { // Convert YIQ -> RGB double i = (c.getRed() * 0.596 - c.getGreen() * 0.275 - c.getBlue() * 0.321); double q = (c.getRed() * 0.212 - c.getGreen() * 0.523 + c.getBlue() * 0.311); // Keep values in legal range. This may reduce the // achieved contrast somewhat. int r = max(0, min(255, (int)round(y + i * 0.956 + q * 0.621))); int g = max(0, min(255, (int)round(y - i * 0.272 - q * 0.647))); int b = max(0, min(255, (int)round(y - i * 1.105 + q * 1.702))); return new Color(r, g, b); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Utils.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.event.*; import java.lang.reflect.*; import java.math.BigDecimal; import java.math.BigInteger; import java.util.*; import java.util.concurrent.ExecutionException; import javax.management.*; import javax.management.openmbean.*; import javax.swing.*; import javax.swing.text.*; class Utils { private Utils() { } private static Set tableNavigationKeys = new HashSet(Arrays.asList(new Integer[] { KeyEvent.VK_TAB, KeyEvent.VK_ENTER, KeyEvent.VK_HOME, KeyEvent.VK_END, KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT, KeyEvent.VK_UP, KeyEvent.VK_DOWN, KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN})); private static final Set> primitiveWrappers = new HashSet>(Arrays.asList(new Class[] { Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Character.class, Boolean.class})); private static final Set> primitives = new HashSet>(); private static final Map> primitiveMap = new HashMap>(); private static final Map> primitiveToWrapper = new HashMap>(); private static final Set editableTypes = new HashSet(); private static final Set> extraEditableClasses = new HashSet>(Arrays.asList(new Class[] { BigDecimal.class, BigInteger.class, Number.class, String.class, String[].class, ObjectName.class})); private static final Set numericalTypes = new HashSet(); private static final Set extraNumericalTypes = new HashSet(Arrays.asList(new String[] { BigDecimal.class.getName(), BigInteger.class.getName(), Number.class.getName()})); private static final Set booleanTypes = new HashSet(Arrays.asList(new String[] { Boolean.TYPE.getName(), Boolean.class.getName()})); static { // compute primitives/primitiveMap/primitiveToWrapper for (Class c : primitiveWrappers) { try { Field f = c.getField("TYPE"); // NOI18N Class p = (Class) f.get(null); primitives.add(p); primitiveMap.put(p.getName(), p); primitiveToWrapper.put(p.getName(), c); } catch (Exception e) { throw new AssertionError(e); } } // compute editableTypes for (Class c : primitives) { editableTypes.add(c.getName()); } for (Class c : primitiveWrappers) { editableTypes.add(c.getName()); } for (Class c : extraEditableClasses) { editableTypes.add(c.getName()); } // compute numericalTypes for (Class c : primitives) { String name = c.getName(); if (!name.equals(Boolean.TYPE.getName())) { numericalTypes.add(name); } } for (Class c : primitiveWrappers) { String name = c.getName(); if (!name.equals(Boolean.class.getName())) { numericalTypes.add(name); } } } /** * This method returns the class matching the name className. * It's used to cater for the primitive types. */ public static Class getClass(String className) throws ClassNotFoundException { Class c; if ((c = primitiveMap.get(className)) != null) return c; return Class.forName(className); } /** * Check if the given collection is a uniform collection of the given type. */ public static boolean isUniformCollection(Collection c, Class e) { if (e == null) { throw new IllegalArgumentException("Null reference type"); // NOI18N } if (c == null) { throw new IllegalArgumentException("Null collection"); // NOI18N } if (c.isEmpty()) { return false; } for (Object o : c) { if (o == null || !e.isAssignableFrom(o.getClass())) { return false; } } return true; } /** * Check if the given element denotes a supported array-friendly data * structure, i.e. a data structure jconsole can render as an array. */ public static boolean canBeRenderedAsArray(Object elem) { if (isSupportedArray(elem)) return true; if (elem instanceof Collection) { Collection c = (Collection) elem; if (c.isEmpty()) { // Empty collections of any Java type are not handled as arrays // return false; } else { // - Collections of CompositeData/TabularData are not handled // as arrays // - Collections of other Java types are handled as arrays // return !isUniformCollection(c, CompositeData.class) && !isUniformCollection(c, TabularData.class); } } if (elem instanceof Map) { return !(elem instanceof TabularData); } return false; } /** * Check if the given element is an array. * * Multidimensional arrays are not supported. * * Non-empty 1-dimensional arrays of CompositeData * and TabularData are not handled as arrays but as * tabular data. */ public static boolean isSupportedArray(Object elem) { if (elem == null || !elem.getClass().isArray()) { return false; } Class ct = elem.getClass().getComponentType(); if (ct.isArray()) { return false; } if (Array.getLength(elem) > 0 && (CompositeData.class.isAssignableFrom(ct) || TabularData.class.isAssignableFrom(ct))) { return false; } return true; } /** * This method provides a readable classname if it's an array, * i.e. either the classname of the component type for arrays * of java reference types or the name of the primitive type * for arrays of java primitive types. Otherwise, it returns null. */ public static String getArrayClassName(String name) { String className = null; if (name.startsWith("[")) { // NOI18N int index = name.lastIndexOf("["); // NOI18N className = name.substring(index, name.length()); if (className.startsWith("[L")) { // NOI18N className = className.substring(2, className.length() - 1); } else { try { Class c = Class.forName(className); className = c.getComponentType().getName(); } catch (ClassNotFoundException e) { // Should not happen throw new IllegalArgumentException( "Bad class name " + name, e); // NOI18N } } } return className; } /** * This methods provides a readable classname. If the supplied name * parameter denotes an array this method returns either the classname * of the component type for arrays of java reference types or the name * of the primitive type for arrays of java primitive types followed by * n-times "[]" where 'n' denotes the arity of the array. Otherwise, if * the supplied name doesn't denote an array it returns the same classname. */ public static String getReadableClassName(String name) { String className = getArrayClassName(name); if (className == null) return name; int index = name.lastIndexOf("["); // NOI18N StringBuilder brackets = new StringBuilder(className); for (int i = 0; i <= index; i++) { brackets.append("[]"); // NOI18N } return brackets.toString(); } /** * This method tells whether the type is editable * (means can be created with a String or not) */ public static boolean isEditableType(String type) { return editableTypes.contains(type); } /** * This method inserts a default value for the standard java types, * else it inserts the text name of the expected class type. * It acts to give a clue as to the input type. */ public static String getDefaultValue(String type) { if (numericalTypes.contains(type) || extraNumericalTypes.contains(type)) { return "0"; // NOI18N } if (booleanTypes.contains(type)) { return "true"; // NOI18N } type = getReadableClassName(type); int i = type.lastIndexOf('.'); if (i > 0) { return type.substring(i + 1, type.length()); } else { return type; } } /** * Try to create a Java object using a one-string-param constructor. */ public static Object newStringConstructor(String type, String param) throws Exception { Constructor c = Utils.getClass(type).getConstructor(String.class); try { return c.newInstance(param); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t instanceof Exception) { throw (Exception) t; } else { throw e; } } } /** * Try to convert a string value into a numerical value. */ private static Number createNumberFromStringValue(String type, String value) throws NumberFormatException { final String suffix = value.substring(value.length() - 1); if ("L".equalsIgnoreCase(suffix)) { // NOI18N return Long.valueOf(value.substring(0, value.length() - 1)); } if ("F".equalsIgnoreCase(suffix)) { // NOI18N return Float.valueOf(value.substring(0, value.length() - 1)); } if ("D".equalsIgnoreCase(suffix)) { // NOI18N return Double.valueOf(value.substring(0, value.length() - 1)); } try { return (Number) newStringConstructor(type, value); } catch (Exception ex) { // OK: Ignore exception... } try { return Integer.valueOf(value); } catch (NumberFormatException e) { // OK: Ignore exception... } try { return Long.valueOf(value); } catch (NumberFormatException e1) { // OK: Ignore exception... } try { return Double.valueOf(value); } catch (NumberFormatException e2) { // OK: Ignore exception... } throw new NumberFormatException("Cannot convert string value '" + // NOI18N value + "' into a numerical value"); // NOI18N } /** * This method attempts to create an object of the given "type" * using the "value" parameter. * e.g. calling createObjectFromString("java.lang.Integer", "10") * will return an Integer object initialized to 10. */ public static Object createObjectFromString(String type, String value) throws Exception { Object result; if (primitiveToWrapper.containsKey(type)) { if (type.equals(Character.TYPE.getName())) { result = new Character(value.charAt(0)); } else { result = newStringConstructor( ((Class) primitiveToWrapper.get(type)).getName(), value); } } else if (type.equals(Character.class.getName())) { result = new Character(value.charAt(0)); } else if (Number.class.isAssignableFrom(Utils.getClass(type))) { result = createNumberFromStringValue(type, value); } else if (String[].class.isAssignableFrom(Utils.getClass(type))) { String[] args = value.split(","); // NOI18N for (int i = 0; i < args.length; i++) { args[i] = args[i].trim(); } result = args; } else if (value == null || value.toString().equals("null")) { // NOI18N // hack for null value result = null; } else { // try to create a Java object using // the one-string-param constructor result = newStringConstructor(type, value); } return result; } /** * This method is responsible for converting the inputs given by the user * into a useful object array for passing into a parameter array. */ public static Object[] getParameters(XTextField[] inputs, String[] params) throws Exception { Object result[] = new Object[inputs.length]; Object userInput; for (int i = 0; i < inputs.length; i++) { userInput = inputs[i].getValue(); // if it's already a complex object, use the value // else try to instantiate with string constructor if (userInput instanceof XObject) { result[i] = ((XObject) userInput).getObject(); } else { result[i] = createObjectFromString(params[i].toString(), (String) userInput); } } return result; } /** * If the exception is wrapped, unwrap it. */ public static Throwable getActualException(Throwable e) { if (e instanceof ExecutionException) e = e.getCause(); if (e instanceof MBeanException || e instanceof RuntimeMBeanException || e instanceof RuntimeOperationsException || e instanceof ReflectionException) { Throwable t = e.getCause(); if (t != null) return t; } return e; } @SuppressWarnings("serial") public static class ReadOnlyTableCellEditor extends DefaultCellEditor { public ReadOnlyTableCellEditor(JTextField tf) { super(tf); tf.addFocusListener(new Utils.EditFocusAdapter(this)); tf.addKeyListener(new Utils.CopyKeyAdapter()); } } public static class EditFocusAdapter extends FocusAdapter { private CellEditor editor; public EditFocusAdapter(CellEditor editor) { this.editor = editor; } @Override public void focusLost(FocusEvent e) { editor.stopCellEditing(); } }; public static class CopyKeyAdapter extends KeyAdapter { private static final String defaultEditorKitCopyActionName = DefaultEditorKit.copyAction; private static final String transferHandlerCopyActionName = (String) TransferHandler.getCopyAction().getValue(Action.NAME); @Override public void keyPressed(KeyEvent e) { // Accept "copy" key strokes KeyStroke ks = KeyStroke.getKeyStroke( e.getKeyCode(), e.getModifiers()); JComponent comp = (JComponent) e.getSource(); for (int i = 0; i < 3; i++) { InputMap im = comp.getInputMap(i); Object key = im.get(ks); if (defaultEditorKitCopyActionName.equals(key) || transferHandlerCopyActionName.equals(key)) { return; } } // Accept JTable navigation key strokes if (!tableNavigationKeys.contains(e.getKeyCode())) { e.consume(); } } @Override public void keyTyped(KeyEvent e) { e.consume(); } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/VariableGridLayout.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.*; import java.util.*; import javax.swing.*; @SuppressWarnings("serial") class VariableGridLayout extends GridLayout { private boolean fillRows, fillColumns; public VariableGridLayout(int rows, int cols, int hgap, int vgap, boolean fillRows, boolean fillColumns) { super(rows, cols, hgap, vgap); this.fillRows = fillRows; this.fillColumns = fillColumns; } public void setFillRow(JComponent c, boolean b) { c.putClientProperty("VariableGridLayout.fillRow", b); // NOI18N } public void setFillColumn(JComponent c, boolean b) { c.putClientProperty("VariableGridLayout.fillColumn", b); // NOI18N } public boolean getFillRow(JComponent c) { Boolean b = (Boolean)c.getClientProperty("VariableGridLayout.fillRow"); // NOI18N return (b != null) ? b : fillRows; } public boolean getFillColumn(JComponent c) { Boolean b = (Boolean)c.getClientProperty("VariableGridLayout.fillColumn"); // NOI18N return (b != null) ? b : fillColumns; } @Override public void layoutContainer(Container parent) { Insets insets = parent.getInsets(); int ncomponents = parent.getComponentCount(); int nrows = getRows(); int ncols = getColumns(); int hgap = getHgap(); int vgap = getVgap(); if (nrows > 0) { ncols = (ncomponents + nrows - 1) / nrows; } else { nrows = (ncomponents + ncols - 1) / ncols; } // Set heights int x; int y; int nFills = 0; boolean[] fills = new boolean[nrows]; int lastFillRow = -1; int nComps = parent.getComponentCount(); y = insets.top; for (int row = 0; row < nrows; row++) { // Find largest minimum height for this row int h = 0; for (int col = 0; col < ncols; col++) { if (row * ncols + col < nComps) { Component c = parent.getComponent(row * ncols + col); h = Math.max(h, c.getMinimumSize().height); } } // Set heights for this row x = insets.left; for (int col = 0; col < ncols; col++) { if (row * ncols + col < nComps) { JComponent c = (JComponent)parent.getComponent(row * ncols + col); int w = c.getWidth(); c.setBounds(x, y, w, h); x += w + hgap; if (col == 0 && getFillRow(c)) { fills[row] = true; } } } y += h + vgap; if (fills[row]) { nFills++; lastFillRow = row; } } // Fill heights if (nFills > 0 && y < parent.getHeight()) { // How much height to add int hAdd = (parent.getHeight() - y) / nFills; int hAdded = 0; for (int row = 0; row < nrows; row++) { if (fills[row]) { if (row == lastFillRow) { // Compensate for rounding error hAdd = parent.getHeight() - (y+hAdded); } for (int col = 0; col < ncols; col++) { if (row * ncols + col < nComps) { Component c = parent.getComponent(row * ncols + col); Rectangle b = c.getBounds(); c.setBounds(b.x, b.y + hAdded, b.width, b.height + hAdd); } } hAdded += hAdd; } } } // Set widths nFills = 0; fills = new boolean[ncols]; int lastFillCol = -1; x = insets.left; for (int col = 0; col < ncols; col++) { // Find largest minimum width for this column int w = 0; for (int row = 0; row < nrows; row++) { if (row * ncols + col < nComps) { Component c = parent.getComponent(row * ncols + col); w = Math.max(w, c.getMinimumSize().width); } } // Set widths for this column y = insets.top; for (int row = 0; row < nrows; row++) { if (row * ncols + col < nComps) { JComponent c = (JComponent)parent.getComponent(row * ncols + col); int h = c.getHeight(); c.setBounds(x, y, w, h); y += h + vgap; if (row == 0 && getFillColumn(c)) { fills[col] = true; } } } x += w + hgap; if (fills[col]) { nFills++; lastFillCol = col; } } // Fill widths if (nFills > 0 && x < parent.getWidth()) { // How much width to add int wAdd = (parent.getWidth() - x) / nFills; int wAdded = 0; for (int col = 0; col < ncols; col++) { if (fills[col]) { if (col == lastFillCol) { wAdd = parent.getWidth() - (x+wAdded); } for (int row = 0; row < nrows; row++) { if (row * ncols + col < nComps) { Component c = parent.getComponent(row * ncols + col); Rectangle b = c.getBounds(); c.setBounds(b.x + wAdded, b.y, b.width + wAdd, b.height); } } wAdded += wAdd; } } } } @Override public Dimension preferredLayoutSize(Container parent) { Insets insets = parent.getInsets(); int ncomponents = parent.getComponentCount(); int nrows = getRows(); int ncols = getColumns(); int hgap = getHgap(); int vgap = getVgap(); if (nrows > 0) { ncols = (ncomponents + nrows - 1) / nrows; } else { nrows = (ncomponents + ncols - 1) / ncols; } int nComps = parent.getComponentCount(); int y = insets.top; for (int row = 0; row < nrows; row++) { int h = 0; for (int col = 0; col < ncols; col++) { if (row * ncols + col < nComps) { Component c = parent.getComponent(row * ncols + col); h = Math.max(h, c.getMinimumSize().height); } } y += h + vgap; } int x = insets.left; for (int col = 0; col < ncols; col++) { int w = 0; for (int row = 0; row < nrows; row++) { if (row * ncols + col < nComps) { Component c = parent.getComponent(row * ncols + col); w = Math.max(w, c.getMinimumSize().width); } } x += w + hgap; } return new Dimension(x, y); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XArrayDataViewer.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.Color; import java.awt.Component; import java.lang.reflect.Array; import java.util.Collection; import java.util.Map; import javax.swing.JEditorPane; import javax.swing.JScrollPane; class XArrayDataViewer { private XArrayDataViewer() {} public static boolean isViewableValue(Object value) { return Utils.canBeRenderedAsArray(value); } public static Component loadArray(Object value) { Component comp = null; if (isViewableValue(value)) { Object[] arr; if (value instanceof Collection) { arr = ((Collection) value).toArray(); } else if (value instanceof Map) { arr = ((Map) value).entrySet().toArray(); } else if (value instanceof Object[]) { arr = (Object[]) value; } else { int length = Array.getLength(value); arr = new Object[length]; for (int i = 0; i < length; i++) { arr[i] = Array.get(value, i); } } JEditorPane arrayEditor = new JEditorPane(); arrayEditor.setContentType("text/html"); // NOI18N arrayEditor.setEditable(false); Color evenRowColor = arrayEditor.getBackground(); int red = evenRowColor.getRed(); int green = evenRowColor.getGreen(); int blue = evenRowColor.getBlue(); String evenRowColorStr = "rgb(" + red + "," + green + "," + blue + ")"; // NOI18N Color oddRowColor = new Color( red < 20 ? red + 20 : red - 20, green < 20 ? green + 20 : green - 20, blue < 20 ? blue + 20 : blue - 20); String oddRowColorStr = "rgb(" + oddRowColor.getRed() + "," + // NOI18N oddRowColor.getGreen() + "," + // NOI18N oddRowColor.getBlue() + ")"; // NOI18N Color foreground = arrayEditor.getForeground(); String textColor = String.format("%06x", // NOI18N foreground.getRGB() & 0xFFFFFF); StringBuilder sb = new StringBuilder(); sb.append(""); // NOI18N for (int i = 0; i < arr.length; i++) { if (i % 2 == 0) { sb.append(""); // NOI18N } else { sb.append(""); // NOI18N } } if (arr.length == 0) { sb.append(""); // NOI18N } sb.append("
" + // NOI18N
                            (arr[i] == null ?
                                arr[i] : htmlize(arr[i].toString())) +
                            "
" + // NOI18N
                            (arr[i] == null ?
                                arr[i] : htmlize(arr[i].toString())) +
                            "
"); // NOI18N arrayEditor.setText(sb.toString()); JScrollPane scrollp = new JScrollPane(arrayEditor); comp = scrollp; } return comp; } private static String htmlize(String value) { return value.replace("&", "&").replace("<", "<"); // NOI18N } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XDataViewer.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import javax.swing.JTable; import javax.swing.JScrollPane; import javax.swing.JButton; import java.awt.event.MouseListener; import java.awt.Component; import java.awt.Container; class XDataViewer { public static final int OPEN = 1; public static final int ARRAY = 2; public static final int NUMERIC = 3; public static final int NOT_SUPPORTED = 4; private MBeansTab tab; public XDataViewer(MBeansTab tab) { this.tab = tab; } public static void registerForMouseEvent(Component comp, MouseListener mouseListener) { if(comp instanceof JScrollPane) { JScrollPane pane = (JScrollPane) comp; comp = pane.getViewport().getView(); } if(comp instanceof Container) { Container container = (Container) comp; Component[] components = container.getComponents(); for(int i = 0; i < components.length; i++) { registerForMouseEvent(components[i], mouseListener); } } //No registration for XOpenTypedata that are themselves clickable. //No registration for JButton that are themselves clickable. if(comp != null && (!(comp instanceof XOpenTypeViewer.XOpenTypeData) && !(comp instanceof JButton)) ) comp.addMouseListener(mouseListener); } public static void dispose(MBeansTab tab) { XPlottingViewer.dispose(tab); } public static boolean isViewableValue(Object value) { boolean ret = false; if((ret = XArrayDataViewer.isViewableValue(value))) return ret; if((ret = XOpenTypeViewer.isViewableValue(value))) return ret; if((ret = XPlottingViewer.isViewableValue(value))) return ret; return ret; } public static int getViewerType(Object data) { if(XArrayDataViewer.isViewableValue(data)) return ARRAY; if(XOpenTypeViewer.isViewableValue(data)) return OPEN; if(XPlottingViewer.isViewableValue(data)) return NUMERIC; return NOT_SUPPORTED; } public static String getActionLabel(int type) { if(type == ARRAY || type == OPEN) return Resources.getText("LBL_visualize"); // NOI18N if(type == NUMERIC) return Resources.getText("LBL_plot"); // NOI18N return Resources.getText("LBL_expand"); // NOI18N } public Component createOperationViewer(Object value, XMBean mbean) { if (value instanceof Number) return null; if (value instanceof Component) return (Component) value; return createAttributeViewer(value, mbean, null, null); } public static Component createNotificationViewer(Object value) { Component comp = null; if(value instanceof Number) return null; if((comp = XArrayDataViewer.loadArray(value)) != null) return comp; if((comp = XOpenTypeViewer.loadOpenType(value)) != null) return comp; return comp; } public Component createAttributeViewer(Object value, XMBean mbean, String attributeName, JTable table) { Component comp = null; if((comp = XArrayDataViewer.loadArray(value)) != null) return comp; if((comp = XOpenTypeViewer.loadOpenType(value)) != null) return comp; if((comp = XPlottingViewer.loadPlotting(mbean, attributeName, value, table, tab)) != null) return comp; return comp; } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XMBean.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import org.graalvm.visualvm.tools.jmx.CachedMBeanServerConnection; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.*; import javax.swing.Icon; class XMBean { private final MBeansTab mbeansTab; private final ObjectName objectName; private Icon icon; private String text; private Boolean broadcaster; private final Object broadcasterLock = new Object(); private MBeanInfo mbeanInfo; private final Object mbeanInfoLock = new Object(); private final static Logger LOGGER = Logger.getLogger(XMBean.class.getName()); public XMBean(ObjectName objectName, MBeansTab mbeansTab) { this.mbeansTab = mbeansTab; this.objectName = objectName; text = objectName.getKeyProperty("name"); // NOI18N if (text == null) text = objectName.getDomain(); if (MBeanServerDelegate.DELEGATE_NAME.equals(objectName)) { icon = IconManager.MBEANSERVERDELEGATE; } else { icon = IconManager.MBEAN; } } MBeanServerConnection getMBeanServerConnection() { return mbeansTab.getMBeanServerConnection(); } CachedMBeanServerConnection getCachedMBeanServerConnection() { return mbeansTab.getCachedMBeanServerConnection(); } public Boolean isBroadcaster() { synchronized (broadcasterLock) { if (broadcaster == null) { try { broadcaster = getMBeanServerConnection().isInstanceOf( getObjectName(), "javax.management.NotificationBroadcaster"); // NOI18N } catch (Exception e) { LOGGER.log(Level.SEVERE, "Couldn't check if MBean [" + // NOI18N objectName + "] is a notification broadcaster", e); // NOI18N return false; } } return broadcaster; } } public Object invoke(String operationName) throws Exception { Object result = getMBeanServerConnection().invoke( getObjectName(), operationName, new Object[0], new String[0]); return result; } public Object invoke(String operationName, Object params[], String sig[]) throws Exception { Object result = getMBeanServerConnection().invoke( getObjectName(), operationName, params, sig); return result; } public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InstanceNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException, IOException { getMBeanServerConnection().setAttribute(getObjectName(), attribute); } public Object getAttribute(String attributeName) throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException { return getCachedMBeanServerConnection().getAttribute( getObjectName(), attributeName); } public AttributeList getAttributes(String attributeNames[]) throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException { return getCachedMBeanServerConnection().getAttributes( getObjectName(), attributeNames); } public AttributeList getAttributes(MBeanAttributeInfo attributeNames[]) throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException { String attributeString[] = new String[attributeNames.length]; for (int i = 0; i < attributeNames.length; i++) { attributeString[i] = attributeNames[i].getName(); } return getAttributes(attributeString); } public ObjectName getObjectName() { return objectName; } public MBeanInfo getMBeanInfo() throws InstanceNotFoundException, IntrospectionException, ReflectionException, IOException { synchronized (mbeanInfoLock) { if (mbeanInfo == null) { mbeanInfo = getMBeanServerConnection().getMBeanInfo(objectName); } return mbeanInfo; } } @Override public boolean equals(Object obj) { if (obj == null) return false; if (obj == this) return true; if (!(obj instanceof XMBean)) return false; XMBean that = (XMBean) obj; return getObjectName().equals(that.getObjectName()); } @Override public int hashCode() { return (objectName == null ? 0 : objectName.hashCode()); } public String getText() { return text; } public void setText(String text) { this.text = text; } public Icon getIcon() { return icon; } public void setIcon(Icon icon) { this.icon = icon; } @Override public String toString() { return getText(); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XMBeanAttributes.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import org.graalvm.visualvm.tools.jmx.CachedMBeanServerConnection; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import java.awt.Component; import java.awt.EventQueue; import java.awt.event.*; import java.awt.Dimension; import java.io.IOException; import java.util.*; import java.lang.reflect.Array; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.*; import javax.management.openmbean.CompositeData; import javax.management.openmbean.TabularData; /*IMPORTANT : There is a deadlock issue there if we don't synchronize well loadAttributes, refresh attributes and empty table methods since a UI thread can call loadAttributes and at the same time a JMX notification can raise an emptyTable. Since there are synchronization in the JMX world it's COMPULSORY to not call the JMX world in synchronized blocks */ class XMBeanAttributes extends XTable { private static final Logger LOGGER = Logger.getLogger(XMBeanAttributes.class.getName()); private final static String[] columnNames = {Resources.getText("LBL_Name"), // NOI18N Resources.getText("LBL_Value")}; // NOI18N private XMBean mbean; private MBeanInfo mbeanInfo; private MBeanAttributeInfo[] attributesInfo; private HashMap attributes; private HashMap unavailableAttributes; private HashMap viewableAttributes; private WeakHashMap> viewersCache = new WeakHashMap>(); private final TableModelListener attributesListener; private MBeansTab mbeansTab; private TableCellEditor valueCellEditor = new ValueCellEditor(); private int rowMinHeight = -1; private AttributesMouseListener mouseListener = new AttributesMouseListener(); private static TableCellEditor editor = new Utils.ReadOnlyTableCellEditor(new JTextField()); public XMBeanAttributes(MBeansTab mbeansTab) { super(); this.mbeansTab = mbeansTab; ((DefaultTableModel)getModel()).setColumnIdentifiers(columnNames); attributesListener = new AttributesListener(this); getModel().addTableModelListener(attributesListener); getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(40); addMouseListener(mouseListener); getTableHeader().setReorderingAllowed(false); setColumnEditors(); addKeyListener(new Utils.CopyKeyAdapter()); } @Override public synchronized Component prepareRenderer(TableCellRenderer renderer, int row, int column) { //In case we have a repaint thread that is in the process of //repainting an obsolete table, just ignore the call. //It can happen when MBean selection is switched at a very quick rate if(row >= getRowCount()) return null; else return super.prepareRenderer(renderer, row, column); } void updateRowHeight(Object obj, int row) { ZoomedCell cell = null; if(obj instanceof ZoomedCell) { cell = (ZoomedCell) obj; if(cell.isInited()) setRowHeight(row, cell.getHeight()); else if(rowMinHeight != - 1) setRowHeight(row, rowMinHeight); } else if(rowMinHeight != - 1) setRowHeight(row, rowMinHeight); } @Override public synchronized TableCellRenderer getCellRenderer(int row, int column) { //In case we have a repaint thread that is in the process of //repainting an obsolete table, just ignore the call. //It can happen when MBean selection is switched at a very quick rate if (row >= getRowCount()) { return null; } else { if (column == VALUE_COLUMN) { Object obj = getModel().getValueAt(row, column); if (obj instanceof ZoomedCell) { ZoomedCell cell = (ZoomedCell) obj; if (cell.isInited()) { DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) cell.getRenderer(); renderer.setToolTipText(getToolTip(row,column)); return renderer; } } } DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) super.getCellRenderer(row, column); if (!isCellError(row, column)) { if (!(isColumnEditable(column) && isWritable(row) && Utils.isEditableType(getClassName(row)))) { renderer.setForeground(getDefaultColor()); } } return renderer; } } private void setColumnEditors() { TableColumnModel tcm = getColumnModel(); for (int i = 0; i < columnNames.length; i++) { TableColumn tc = tcm.getColumn(i); if (isColumnEditable(i)) { tc.setCellEditor(valueCellEditor); } else { tc.setCellEditor(editor); } } } public void cancelCellEditing() { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("Cancel Editing Row: "+getEditingRow()); } final TableCellEditor tableCellEditor = getCellEditor(); if (tableCellEditor != null) { tableCellEditor.cancelCellEditing(); } } public void stopCellEditing() { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("Stop Editing Row: "+getEditingRow()); } final TableCellEditor tableCellEditor = getCellEditor(); if (tableCellEditor != null) { tableCellEditor.stopCellEditing(); } } @Override public final boolean editCellAt(final int row, final int column, EventObject e) { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("editCellAt(row="+row+", col="+column+ ", e="+e+")"); } boolean retVal = super.editCellAt(row, column, e); if (retVal) { final TableCellEditor tableCellEditor = getColumnModel().getColumn(column).getCellEditor(); if (tableCellEditor == valueCellEditor) { ((JComponent) tableCellEditor).requestFocus(); } } return retVal; } @Override public boolean isCellEditable(int row, int col) { // All the cells in non-editable columns are editable if (!isColumnEditable(col)) { return true; } // Maximized zoomed cells are editable Object obj = getModel().getValueAt(row, col); if (obj instanceof ZoomedCell) { ZoomedCell cell = (ZoomedCell) obj; return cell.isMaximized(); } return true; } @Override public void setValueAt(Object value, int row, int column) { if (!isCellError(row, column) && isColumnEditable(column) && isWritable(row) && Utils.isEditableType(getClassName(row))) { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("setValueAt(row="+row+", column="+column+ "): "+getValueName(row)+"="+value); } super.setValueAt(value, row, column); } } //Table methods public boolean isTableEditable() { return true; } public void setTableValue(Object value, int row) { } public boolean isColumnEditable(int column) { if (column < getColumnCount()) { return getColumnName(column).equals(Resources.getText("LBL_Value")); // NOI18N } else { return false; } } public String getClassName(int row) { int index = convertRowToIndex(row); if (index != -1) { return attributesInfo[index].getType(); } else { return null; } } public String getValueName(int row) { int index = convertRowToIndex(row); if (index != -1) { return attributesInfo[index].getName(); } else { return null; } } public Object getValue(int row) { final Object val = ((DefaultTableModel) getModel()) .getValueAt(row, VALUE_COLUMN); return val; } //tool tip only for editable column @Override public String getToolTip(int row, int column) { if (isCellError(row, column)) { return (String) unavailableAttributes.get(getValueName(row)); } if (isColumnEditable(column)) { Object value = getValue(row); String tip = null; if (value != null) { tip = value.toString(); if(isAttributeViewable(row, VALUE_COLUMN)) tip = Resources.getText("LBL_DoubleClickToExpandCollapse")+ // NOI18N ". " + tip; // NOI18N } return tip; } if(column == NAME_COLUMN) { int index = convertRowToIndex(row); if (index != -1) { return attributesInfo[index].getDescription(); } } return null; } public synchronized boolean isWritable(int row) { int index = convertRowToIndex(row); if (index != -1) { return (attributesInfo[index].isWritable()); } else { return false; } } /** * Override JTable method in order to make any call to this method * atomic with TableModel elements. */ @Override public synchronized int getRowCount() { return super.getRowCount(); } public synchronized boolean isReadable(int row) { int index = convertRowToIndex(row); if (index != -1) { return (attributesInfo[index].isReadable()); } else { return false; } } public synchronized boolean isCellError(int row, int col) { return (isColumnEditable(col) && (unavailableAttributes.containsKey(getValueName(row)))); } public synchronized boolean isAttributeViewable(int row, int col) { boolean isViewable = false; if(col == VALUE_COLUMN) { Object obj = getModel().getValueAt(row, col); if(obj instanceof ZoomedCell) isViewable = true; } return isViewable; } // Call this in EDT public void loadAttributes(final XMBean mbean, final MBeanInfo mbeanInfo) { final SwingWorker load = new SwingWorker() { @Override protected Runnable doInBackground() throws Exception { return doLoadAttributes(mbean,mbeanInfo); } @Override protected void done() { try { final Runnable updateUI = get(); if (updateUI != null) updateUI.run(); } catch (RuntimeException x) { throw x; } catch (ExecutionException x) { LOGGER.log(Level.FINE, "Exception raised while loading attributes", x.getCause()); } catch (InterruptedException x) { LOGGER.log(Level.FINE, "Interrupted while loading attributes",x); } } }; mbeansTab.getRequestProcessor().post(load); } // Don't call this in EDT, but execute returned Runnable inside // EDT - typically in the done() method of a SwingWorker // This method can return null. private Runnable doLoadAttributes(final XMBean mbean, MBeanInfo infoOrNull) throws JMException, IOException { // To avoid deadlock with events coming from the JMX side, // we retrieve all JMX stuff in a non synchronized block. if(mbean == null) return null; final MBeanInfo curMBeanInfo = (infoOrNull==null)?mbean.getMBeanInfo():infoOrNull; final MBeanAttributeInfo[] attrsInfo = curMBeanInfo.getAttributes(); final HashMap attrs = new HashMap(attrsInfo.length); final HashMap unavailableAttrs = new HashMap(attrsInfo.length); final HashMap viewableAttrs = new HashMap(attrsInfo.length); AttributeList list = null; try { list = mbean.getAttributes(attrsInfo); }catch(Exception e) { list = new AttributeList(); //Can't load all attributes, do it one after each other. for(int i = 0; i < attrsInfo.length; i++) { String name = null; try { name = attrsInfo[i].getName(); Object value = mbean.getMBeanServerConnection(). getAttribute(mbean.getObjectName(), name); list.add(new Attribute(name, value)); }catch(Exception ex) { if(attrsInfo[i].isReadable()) { unavailableAttrs.put(name, Utils.getActualException(ex).toString()); } } } } try { int att_length = list.size(); for (int i=0;i stopCellEditing -> setValueAt -> tableChanged // -> refreshAttributes(false) // // Can be called in EDT - as long as the implementation of // mbeansTab.getCachedMBeanServerConnection() and mbsc.flush() doesn't // change // private void refreshAttributes(final boolean stopCellEditing) { SwingWorker sw = new SwingWorker() { @Override protected Void doInBackground() throws Exception { CachedMBeanServerConnection mbsc = mbeansTab.getCachedMBeanServerConnection(); mbsc.flush(); return null; } @Override protected void done() { try { get(); if (stopCellEditing) stopCellEditing(); loadAttributes(mbean, mbeanInfo); } catch (Exception x) { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.log(Level.FINER, "Unexpected exception while loading attributes",// No I18N x); } } } }; mbeansTab.getRequestProcessor().post(sw); } // We need to call stop editing here - otherwise edits are lost // when resizing the table. // @Override public void columnMarginChanged(ChangeEvent e) { if (isEditing()) stopCellEditing(); super.columnMarginChanged(e); } // We need to call stop editing here - otherwise the edited value // is transferred to the wrong row... // @Override void sortRequested(int column) { if (isEditing()) stopCellEditing(); super.sortRequested(column); } @Override public synchronized void emptyTable() { emptyTable((DefaultTableModel)getModel()); } // Call this in synchronized block. private void emptyTable(DefaultTableModel model) { model.removeTableModelListener(attributesListener); super.emptyTable(); } private boolean isViewable(Attribute attribute) { Object data = attribute.getValue(); return XDataViewer.isViewableValue(data); } synchronized void removeAttributes() { if (attributes != null) { attributes.clear(); } if (unavailableAttributes != null) { unavailableAttributes.clear(); } if (viewableAttributes != null) { viewableAttributes.clear(); } mbean = null; } private ZoomedCell getZoomedCell(XMBean mbean, String attribute, Object value) { synchronized (viewersCache) { HashMap viewers; if (viewersCache.containsKey(mbean)) { viewers = viewersCache.get(mbean); } else { viewers = new HashMap(); } ZoomedCell cell; if (viewers.containsKey(attribute)) { cell = viewers.get(attribute); cell.setValue(value); if (cell.isMaximized() && cell.getType() != XDataViewer.NUMERIC) { // Plotters are the only viewers with auto update capabilities. // Other viewers need to be updated manually. Component comp = mbeansTab.getDataViewer().createAttributeViewer( value, mbean, attribute, XMBeanAttributes.this); cell.init(cell.getMinRenderer(), comp, cell.getMinHeight()); mbeansTab.getDataViewer().registerForMouseEvent(comp, mouseListener); } } else { cell = new ZoomedCell(value); viewers.put(attribute, cell); } viewersCache.put(mbean, viewers); return cell; } } //will be called in a synchronzed block protected void addTableData(DefaultTableModel tableModel, XMBean mbean, MBeanAttributeInfo[] attributesInfo, HashMap attributes, HashMap unavailableAttributes, HashMap viewableAttributes) { Object rowData[] = new Object[2]; int col1Width = 0; int col2Width = 0; for (int i = 0; i < attributesInfo.length; i++) { rowData[0] = (attributesInfo[i].getName()); if (unavailableAttributes.containsKey(rowData[0])) { rowData[1] = Resources.getText("LBL_Unavailable"); // NOI18N } else if (viewableAttributes.containsKey(rowData[0])) { rowData[1] = viewableAttributes.get(rowData[0]); if (!attributesInfo[i].isWritable() || !Utils.isEditableType(attributesInfo[i].getType())) { rowData[1] = getZoomedCell(mbean, (String) rowData[0], rowData[1]); } } else { rowData[1] = attributes.get(rowData[0]); } tableModel.addRow(rowData); //Update column width // String str = null; if(rowData[0] != null) { str = rowData[0].toString(); if(str.length() > col1Width) col1Width = str.length(); } if(rowData[1] != null) { str = rowData[1].toString(); if(str.length() > col2Width) col2Width = str.length(); } } updateColumnWidth(col1Width, col2Width); } private void updateColumnWidth(int col1Width, int col2Width) { TableColumnModel colModel = getColumnModel(); //Get the column at index pColumn, and set its preferred width. col1Width = col1Width * 7; col2Width = col2Width * 7; if(col1Width + col2Width < (int) getPreferredScrollableViewportSize().getWidth()) col2Width = (int) getPreferredScrollableViewportSize().getWidth() - col1Width; colModel.getColumn(NAME_COLUMN).setPreferredWidth(50); } class AttributesMouseListener extends MouseAdapter { @Override public void mousePressed(MouseEvent e) { if(e.getButton() == MouseEvent.BUTTON1) { if(e.getClickCount() >= 2) { int row = XMBeanAttributes.this.getSelectedRow(); int col = XMBeanAttributes.this.getSelectedColumn(); if(col != VALUE_COLUMN) return; if(col == -1 || row == -1) return; XMBeanAttributes.this.updateZoomedCell(row, col); } } } } @SuppressWarnings("serial") class ValueCellEditor extends XTextFieldEditor { // implements javax.swing.table.TableCellEditor @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { Object val = value; if(column == VALUE_COLUMN) { Object obj = getModel().getValueAt(row, column); if(obj instanceof ZoomedCell) { ZoomedCell cell = (ZoomedCell) obj; if(cell.getRenderer() instanceof MaximizedCellRenderer) { MaximizedCellRenderer zr = (MaximizedCellRenderer) cell.getRenderer(); return zr.getComponent(); } } else { Component comp = super.getTableCellEditorComponent( table, val, isSelected, row, column); if (isCellError(row, column) || !isWritable(row) || !Utils.isEditableType(getClassName(row))) { textField.setEditable(false); } return comp; } } return super.getTableCellEditorComponent(table, val, isSelected, row, column); } @Override public boolean stopCellEditing() { int editingRow = getEditingRow(); int editingColumn = getEditingColumn(); if (editingColumn == VALUE_COLUMN) { Object obj = getModel().getValueAt(editingRow, editingColumn); if (obj instanceof ZoomedCell) { ZoomedCell cell = (ZoomedCell) obj; if (cell.isMaximized()) { this.cancelCellEditing(); return true; } } } return super.stopCellEditing(); } } @SuppressWarnings("serial") class MaximizedCellRenderer extends DefaultTableCellRenderer { Component comp; MaximizedCellRenderer(Component comp) { this.comp = comp; Dimension d = comp.getPreferredSize(); if (d.getHeight() > 220) { comp.setPreferredSize(new Dimension((int) d.getWidth(), 220)); } } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { return comp; } public Component getComponent() { return comp; } } class ZoomedCell { TableCellRenderer minRenderer; MaximizedCellRenderer maxRenderer; int minHeight; boolean minimized = true; boolean init = false; int type; Object value; ZoomedCell(Object value) { type = XDataViewer.getViewerType(value); this.value = value; } boolean isInited() { return init; } Object getValue() { return value; } void setValue(Object value) { this.value = value; } void init(TableCellRenderer minRenderer, Component maxComponent, int minHeight) { this.minRenderer = minRenderer; this.maxRenderer = new MaximizedCellRenderer(maxComponent); this.minHeight = minHeight; init = true; } int getType() { return type; } void reset() { init = false; minimized = true; } void switchState() { minimized = !minimized; } boolean isMaximized() { return !minimized; } void minimize() { minimized = true; } void maximize() { minimized = false; } int getHeight() { if(minimized) return minHeight; else return (int) maxRenderer.getComponent(). getPreferredSize().getHeight() ; } int getMinHeight() { return minHeight; } @Override public String toString() { if(value == null) return null; if(value.getClass().isArray()) { String name = Utils.getArrayClassName(value.getClass().getName()); int length = Array.getLength(value); return name + "[" + length +"]"; // NOI18N } if(value instanceof CompositeData || value instanceof TabularData) return value.getClass().getName(); return value.toString(); } TableCellRenderer getRenderer() { if(minimized) return minRenderer; else return maxRenderer; } TableCellRenderer getMinRenderer() { return minRenderer; } } class AttributesListener implements TableModelListener { private Component component; public AttributesListener(Component component) { this.component = component; } // Call this in EDT public void tableChanged(final TableModelEvent e) { // only post changes to the draggable column if (isColumnEditable(e.getColumn())) { final TableModel model = (TableModel)e.getSource(); Object tableValue = model.getValueAt(e.getFirstRow(), e.getColumn()); if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("tableChanged: firstRow="+e.getFirstRow()+ ", lastRow="+e.getLastRow()+", column="+e.getColumn()+ ", value="+tableValue); } // if it's a String, try construct new value // using the defined type. if (tableValue instanceof String) { try { tableValue = Utils.createObjectFromString(getClassName(e.getFirstRow()), // type (String)tableValue);// value } catch (Throwable ex) { popupAndLog(ex,"tableChanged", "LBL_ProblemSettingAttribute"); } } final String attributeName = getValueName(e.getFirstRow()); final Attribute attribute = new Attribute(attributeName,tableValue); setAttribute(attribute, "tableChanged"); } } // Call this in EDT private void setAttribute(final Attribute attribute, final String method) { final SwingWorker setAttribute = new SwingWorker() { @Override protected Void doInBackground() throws Exception { try { mbean.setAttribute(attribute); } catch (Throwable ex) { popupAndLog(ex,method,"LBL_ProblemSettingAttribute"); } return null; } @Override protected void done() { try { get(); } catch (Exception x) { // XX should not happen // XXX log this } refreshAttributes(false); } }; mbeansTab.getRequestProcessor().post(setAttribute); } // Call this outside EDT private void popupAndLog(Throwable ex, String method, String key) { ex = Utils.getActualException(ex); LOGGER.throwing(XMBeanAttributes.class.getName(), method, ex); // NOI18N String message = (ex.getMessage() != null) ? ex.getMessage() : ex.toString(); EventQueue.invokeLater( new ThreadDialog(component, message+"\n", // NOI18N Resources.getText(key), // NOI18N JOptionPane.ERROR_MESSAGE)); } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XMBeanInfo.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.util.*; import javax.management.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import static org.graalvm.visualvm.modules.mbeans.Utilities.*; @SuppressWarnings("serial") class XMBeanInfo extends JPanel { private static final Color lightSalmon = new Color(255, 160, 122); private static final Color lightYellow = new Color(255, 255, 128); private final int NAME_COLUMN = 0; private final int VALUE_COLUMN = 1; private final String[] columnNames = { Resources.getText("LBL_Name"), // NOI18N Resources.getText("LBL_Value") // NOI18N }; private JTable infoTable = new JTable(); private static class ReadOnlyDefaultTableModel extends DefaultTableModel { @Override public void setValueAt(Object value, int row, int col) { } } private static class TableRowDivider { public String tableRowDividerText; public Color tableRowDividerColor; public TableRowDivider( String tableRowDividerText, Color tableRowDividerColor) { this.tableRowDividerText = tableRowDividerText; this.tableRowDividerColor = tableRowDividerColor; } @Override public String toString() { return tableRowDividerText; } } private static MBeanInfoTableCellRenderer renderer = new MBeanInfoTableCellRenderer(); private static class MBeanInfoTableCellRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component comp = super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column); if (value instanceof TableRowDivider) { JLabel label = new JLabel( "" + value.toString() + ""); // NOI18N label.setBackground(ensureContrast( ((TableRowDivider) value).tableRowDividerColor, label.getForeground())); label.setOpaque(true); return label; } return comp; } } private static TableCellEditor editor = new MBeanInfoTableCellEditor(new JTextField()); private static class MBeanInfoTableCellEditor extends Utils.ReadOnlyTableCellEditor { public MBeanInfoTableCellEditor(JTextField tf) { super(tf); } @Override public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column) { Component comp = super.getTableCellEditorComponent( table, value, isSelected, row, column); if (value instanceof TableRowDivider) { JLabel label = new JLabel( "" + value.toString() + ""); // NOI18N label.setBackground(ensureContrast( ((TableRowDivider) value).tableRowDividerColor, label.getForeground())); label.setOpaque(true); return label; } return comp; } } public XMBeanInfo() { super(new BorderLayout()); setBorder(BorderFactory.createTitledBorder(Resources.getText("LBL_MBeanInfo"))); // NOI18N infoTable.setModel(new ReadOnlyDefaultTableModel()); infoTable.setRowSelectionAllowed(false); infoTable.setColumnSelectionAllowed(false); infoTable.getTableHeader().setReorderingAllowed(false); ((DefaultTableModel) infoTable.getModel()).setColumnIdentifiers(columnNames); infoTable.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(140); infoTable.getColumnModel().getColumn(NAME_COLUMN).setMaxWidth(140); infoTable.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(renderer); infoTable.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(renderer); infoTable.getColumnModel().getColumn(NAME_COLUMN).setCellEditor(editor); infoTable.getColumnModel().getColumn(VALUE_COLUMN).setCellEditor(editor); infoTable.addKeyListener(new Utils.CopyKeyAdapter()); infoTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); JScrollPane infoTableScrollPane = new JScrollPane(infoTable); add(infoTableScrollPane); } // Call on EDT public void emptyInfoTable() { DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); while (tableModel.getRowCount() > 0) { tableModel.removeRow(0); } } // Call on EDT private void addDescriptor(Descriptor desc, String text) { if (desc != null && desc.getFieldNames().length > 0) { DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; rowData[0] = new TableRowDivider( text + " " + Resources.getText("LBL_Descriptor") + ":", lightYellow); // NOI18N rowData[1] = new TableRowDivider("", lightYellow); // NOI18N tableModel.addRow(rowData); for (String fieldName : desc.getFieldNames()) { rowData[0] = fieldName; Object fieldValue = desc.getFieldValue(fieldName); if (fieldValue instanceof boolean[]) { rowData[1] = Arrays.toString((boolean[]) fieldValue); } else if (fieldValue instanceof byte[]) { rowData[1] = Arrays.toString((byte[]) fieldValue); } else if (fieldValue instanceof char[]) { rowData[1] = Arrays.toString((char[]) fieldValue); } else if (fieldValue instanceof double[]) { rowData[1] = Arrays.toString((double[]) fieldValue); } else if (fieldValue instanceof float[]) { rowData[1] = Arrays.toString((float[]) fieldValue); } else if (fieldValue instanceof int[]) { rowData[1] = Arrays.toString((int[]) fieldValue); } else if (fieldValue instanceof long[]) { rowData[1] = Arrays.toString((long[]) fieldValue); } else if (fieldValue instanceof short[]) { rowData[1] = Arrays.toString((short[]) fieldValue); } else if (fieldValue instanceof Object[]) { rowData[1] = Arrays.toString((Object[]) fieldValue); } else { rowData[1] = fieldValue; } tableModel.addRow(rowData); } tableModel.newDataAvailable(new TableModelEvent(tableModel)); } } // Call on EDT private void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) { String border = Resources.getText("LBL_MBeanInfo"); // NOI18N String text = Resources.getText("LBL_Info"); // NOI18N DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; rowData[0] = new TableRowDivider(border, lightSalmon); rowData[1] = new TableRowDivider("", lightSalmon); // NOI18N tableModel.addRow(rowData); rowData[0] = new TableRowDivider(text + ":", lightYellow); // NOI18N rowData[1] = new TableRowDivider("", lightYellow); // NOI18N tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_ObjectName"); // NOI18N rowData[1] = mbean.getObjectName(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_ClassName"); // NOI18N rowData[1] = mbeanInfo.getClassName(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Description"); // NOI18N rowData[1] = mbeanInfo.getDescription(); tableModel.addRow(rowData); addDescriptor(mbeanInfo.getDescriptor(), text); // MBeanConstructorInfo // int i = 0; for (MBeanConstructorInfo mbci : mbeanInfo.getConstructors()) { addMBeanConstructorInfo(mbci, Resources.getText("LBL_Constructor") + "-" + i); // NOI18N // MBeanParameterInfo // int j = 0; for (MBeanParameterInfo mbpi : mbci.getSignature()) { addMBeanParameterInfo(mbpi, Resources.getText("LBL_Parameter") + "-" + i + "-" + j); // NOI18N j++; } i++; } tableModel.newDataAvailable(new TableModelEvent(tableModel)); } // Call on EDT private void addMBeanAttributeInfo(MBeanAttributeInfo mbai) { String border = Resources.getText("LBL_MBeanAttributeInfo"); // NOI18N String text = Resources.getText("LBL_Attribute"); // NOI18N DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; rowData[0] = new TableRowDivider(border, lightSalmon); rowData[1] = new TableRowDivider("", lightSalmon); // NOI18N tableModel.addRow(rowData); rowData[0] = new TableRowDivider(text + ":", lightYellow); // NOI18N rowData[1] = new TableRowDivider("", lightYellow); // NOI18N tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Name"); // NOI18N rowData[1] = mbai.getName(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Description"); // NOI18N rowData[1] = mbai.getDescription(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Readable"); // NOI18N rowData[1] = mbai.isReadable(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Writable"); // NOI18N rowData[1] = mbai.isWritable(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Is"); // NOI18N rowData[1] = mbai.isIs(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Type"); // NOI18N rowData[1] = mbai.getType(); tableModel.addRow(rowData); addDescriptor(mbai.getDescriptor(), text); tableModel.newDataAvailable(new TableModelEvent(tableModel)); } // Call on EDT private void addMBeanOperationInfo(MBeanOperationInfo mboi) { String border = Resources.getText("LBL_MBeanOperationInfo"); // NOI18N String text = Resources.getText("LBL_Operation"); // NOI18N DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; rowData[0] = new TableRowDivider(border, lightSalmon); rowData[1] = new TableRowDivider("", lightSalmon); // NOI18N tableModel.addRow(rowData); rowData[0] = new TableRowDivider(text + ":", lightYellow); // NOI18N rowData[1] = new TableRowDivider("", lightYellow); // NOI18N tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Name"); // NOI18N rowData[1] = mboi.getName(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Description"); // NOI18N rowData[1] = mboi.getDescription(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Impact"); // NOI18N switch (mboi.getImpact()) { case MBeanOperationInfo.INFO: rowData[1] = Resources.getText("LBL_INFO"); // NOI18N break; case MBeanOperationInfo.ACTION: rowData[1] = Resources.getText("LBL_ACTION"); // NOI18N break; case MBeanOperationInfo.ACTION_INFO: rowData[1] = Resources.getText("LBL_ACTION_INFO"); // NOI18N break; case MBeanOperationInfo.UNKNOWN: rowData[1] = Resources.getText("LBL_UNKNOWN"); // NOI18N break; } tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_ReturnType"); // NOI18N rowData[1] = mboi.getReturnType(); tableModel.addRow(rowData); addDescriptor(mboi.getDescriptor(), text); // MBeanParameterInfo // int i = 0; for (MBeanParameterInfo mbpi : mboi.getSignature()) { addMBeanParameterInfo(mbpi, Resources.getText("LBL_Parameter") + "-" + i++); // NOI18N } tableModel.newDataAvailable(new TableModelEvent(tableModel)); } // Call on EDT private void addMBeanNotificationInfo(MBeanNotificationInfo mbni) { String border = Resources.getText("LBL_MBeanNotificationInfo") + ":"; // NOI18N String text = Resources.getText("LBL_Notification"); // NOI18N DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; rowData[0] = new TableRowDivider(border, lightSalmon); rowData[1] = new TableRowDivider("", lightSalmon); // NOI18N tableModel.addRow(rowData); rowData[0] = new TableRowDivider(text + ":", lightYellow); // NOI18N rowData[1] = new TableRowDivider("", lightYellow); // NOI18N tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Name"); // NOI18N rowData[1] = mbni.getName(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Description"); // NOI18N rowData[1] = mbni.getDescription(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_NotifTypes"); // NOI18N rowData[1] = Arrays.toString(mbni.getNotifTypes()); tableModel.addRow(rowData); addDescriptor(mbni.getDescriptor(), text); tableModel.newDataAvailable(new TableModelEvent(tableModel)); } // Call on EDT private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) { DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; rowData[0] = new TableRowDivider(text + ":", lightYellow); // NOI18N rowData[1] = new TableRowDivider("", lightYellow); // NOI18N tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Name"); // NOI18N rowData[1] = mbci.getName(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Description"); // NOI18N rowData[1] = mbci.getDescription(); tableModel.addRow(rowData); addDescriptor(mbci.getDescriptor(), text); tableModel.newDataAvailable(new TableModelEvent(tableModel)); } // Call on EDT private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) { DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; rowData[0] = new TableRowDivider(text + ":", lightYellow); // NOI18N rowData[1] = new TableRowDivider("", lightYellow); // NOI18N tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Name"); // NOI18N rowData[1] = mbpi.getName(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Description"); // NOI18N rowData[1] = mbpi.getDescription(); tableModel.addRow(rowData); rowData[0] = Resources.getText("LBL_Type"); // NOI18N rowData[1] = mbpi.getType(); tableModel.addRow(rowData); addDescriptor(mbpi.getDescriptor(), text); tableModel.newDataAvailable(new TableModelEvent(tableModel)); } // Call on EDT public void loadMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) { // MBeanInfo // addMBeanInfo(mbean, mbeanInfo); // MBeanAttributeInfo // MBeanAttributeInfo[] ai = mbeanInfo.getAttributes(); if (ai != null && ai.length > 0) { for (MBeanAttributeInfo mbai : ai) { addMBeanAttributeInfo(mbai); } } // MBeanOperationInfo // MBeanOperationInfo[] oi = mbeanInfo.getOperations(); if (oi != null && oi.length > 0) { for (MBeanOperationInfo mboi : oi) { addMBeanOperationInfo(mboi); } } // MBeanNotificationInfo // MBeanNotificationInfo[] ni = mbeanInfo.getNotifications(); if (ni != null && ni.length > 0) { for (MBeanNotificationInfo mbni : ni) { addMBeanNotificationInfo(mbni); } } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XMBeanNotifications.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import javax.swing.tree.*; import java.awt.Font; import java.text.SimpleDateFormat; import java.awt.Component; import java.awt.EventQueue; import java.awt.event.*; import java.awt.Dimension; import java.util.*; import java.io.*; import java.lang.reflect.Array; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.*; import javax.management.openmbean.CompositeData; import javax.management.openmbean.TabularData; class XMBeanNotifications extends JTable implements NotificationListener { private final static String[] columnNames = { Resources.getText("LBL_TimeStamp"), // NOI18N Resources.getText("LBL_Type"), // NOI18N Resources.getText("LBL_UserData"), // NOI18N Resources.getText("LBL_SeqNum"), // NOI18N Resources.getText("LBL_Message"), // NOI18N Resources.getText("LBL_Event"), // NOI18N Resources.getText("LBL_Source")}; // NOI18N private final static Logger LOGGER = Logger.getLogger(XMBeanNotifications.class.getName()); private HashMap listeners = new HashMap(); private volatile boolean subscribed; private XMBeanNotificationsListener currentListener; public final static String NOTIFICATION_RECEIVED_EVENT = "jconsole.xnotification.received"; // NOI18N private List notificationListenersList; private volatile boolean enabled; private Font normalFont, boldFont; private int rowMinHeight = -1; private TableCellEditor userDataEditor = new UserDataCellEditor(); private NotifMouseListener mouseListener = new NotifMouseListener(); private SimpleDateFormat timeFormater = new SimpleDateFormat("HH:mm:ss:SSS"); // NOI18N private static TableCellEditor editor = new Utils.ReadOnlyTableCellEditor(new JTextField()); public XMBeanNotifications() { super(new TableSorter(columnNames,0)); setColumnSelectionAllowed(false); setRowSelectionAllowed(false); getTableHeader().setReorderingAllowed(false); ArrayList l = new ArrayList(1); notificationListenersList = Collections.synchronizedList(l); addMouseListener(mouseListener); TableColumnModel colModel = getColumnModel(); colModel.getColumn(0).setPreferredWidth(45); colModel.getColumn(1).setPreferredWidth(50); colModel.getColumn(2).setPreferredWidth(50); colModel.getColumn(3).setPreferredWidth(40); colModel.getColumn(4).setPreferredWidth(50); colModel.getColumn(5).setPreferredWidth(50); setColumnEditors(); addKeyListener(new Utils.CopyKeyAdapter()); } // Call on EDT public void cancelCellEditing() { TableCellEditor tce = getCellEditor(); if (tce != null) { tce.cancelCellEditing(); } } // Call on EDT public void stopCellEditing() { TableCellEditor tce = getCellEditor(); if (tce != null) { tce.stopCellEditing(); } } // Call on EDT @Override public boolean isCellEditable(int row, int col) { UserDataCell cell = getUserDataCell(row, col); if (cell != null) { return cell.isMaximized(); } return true; } // Call on EDT @Override public void setValueAt(Object value, int row, int column) { } // Call on EDT @Override public synchronized Component prepareRenderer( TableCellRenderer renderer, int row, int column) { //In case we have a repaint thread that is in the process of //repainting an obsolete table, just ignore the call. //It can happen when MBean selection is switched at a very quick rate if (row >= getRowCount()) return null; Component comp = super.prepareRenderer(renderer, row, column); if (normalFont == null) { normalFont = comp.getFont(); boldFont = normalFont.deriveFont(Font.BOLD); } UserDataCell cell = getUserDataCell(row, 2); if (column == 2 && cell != null) { comp.setFont(boldFont); int size = cell.getHeight(); if (size > 0) { if(getRowHeight(row) != size) setRowHeight(row, size); } } else { comp.setFont(normalFont); } return comp; } // Call on EDT @Override public synchronized TableCellRenderer getCellRenderer(int row, int column) { //In case we have a repaint thread that is in the process of //repainting an obsolete table, just ignore the call. //It can happen when MBean selection is switched at a very quick rate if (row >= getRowCount()) return null; DefaultTableCellRenderer renderer; String toolTip = null; UserDataCell cell = getUserDataCell(row, column); if (cell != null && cell.isInited()) { renderer = (DefaultTableCellRenderer) cell.getRenderer(); } else { renderer = (DefaultTableCellRenderer) super.getCellRenderer(row, column); } if (cell != null) toolTip = Resources.getText("LBL_DoubleClickToExpandCollapse") + // NOI18N ". " + cell.toString(); // NOI18N else { Object val = ((DefaultTableModel) getModel()).getValueAt(row, column); if (val != null) toolTip = val.toString(); } renderer.setToolTipText(toolTip); return renderer; } // Call on EDT private UserDataCell getUserDataCell(int row, int column) { Object obj = ((DefaultTableModel) getModel()).getValueAt(row,column); if (obj instanceof UserDataCell) return (UserDataCell) obj; return null; } synchronized void dispose() { listeners.clear(); } public long getReceivedNotifications(XMBean mbean) { XMBeanNotificationsListener listener = listeners.get(mbean.getObjectName()); if (listener == null) return 0; else return listener.getReceivedNotifications(); } public synchronized boolean clearCurrentNotifications() { emptyTable(); if (currentListener != null) { currentListener.clear(); return true; } else return false; } public synchronized boolean unregisterListener(DefaultMutableTreeNode node) { XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData(); return unregister(mbean.getObjectName()); } public synchronized void registerListener(DefaultMutableTreeNode node) throws InstanceNotFoundException, IOException { XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData(); if (!subscribed) { try { mbean.getMBeanServerConnection().addNotificationListener( MBeanServerDelegate.DELEGATE_NAME, this, null, null); subscribed = true; } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error adding listener for delegate", e); // NOI18N } } XMBeanNotificationsListener listener = listeners.get(mbean.getObjectName()); if (listener == null) { listener = new XMBeanNotificationsListener( this, mbean, node, columnNames); listeners.put(mbean.getObjectName(), listener); } else { if (!listener.isRegistered()) { emptyTable(); listener.register(node); } } enabled = true; currentListener = listener; } public synchronized void handleNotification( Notification notif, Object handback) { try { if (notif instanceof MBeanServerNotification) { ObjectName mbean = ((MBeanServerNotification) notif).getMBeanName(); if (notif.getType().indexOf("JMX.mbean.unregistered") >= 0) { // NOI18N unregister(mbean); } } } catch(Exception e) { LOGGER.log(Level.SEVERE, "Error unregistering notification", e); // NOI18N } } public synchronized void disableNotifications() { emptyTable(); currentListener = null; enabled = false; } private synchronized boolean unregister(ObjectName mbean) { XMBeanNotificationsListener listener = listeners.get(mbean); if (listener != null && listener.isRegistered()) { listener.unregister(); return true; } else return false; } public void addNotificationsListener(NotificationListener nl) { notificationListenersList.add(nl); } public void removeNotificationsListener(NotificationListener nl) { notificationListenersList.remove(nl); } // Call on EDT void fireNotificationReceived( XMBeanNotificationsListener listener, XMBean mbean, DefaultMutableTreeNode node, Object[] rowData, long received) { if (enabled) { DefaultTableModel tableModel = (DefaultTableModel) getModel(); if (listener == currentListener) { tableModel.insertRow(0, rowData); repaint(); } } Notification notif = new Notification(NOTIFICATION_RECEIVED_EVENT, this, 0); notif.setUserData(received); for (NotificationListener nl : notificationListenersList) nl.handleNotification(notif, node); } // Call on EDT private void updateModel(List data) { emptyTable(); DefaultTableModel tableModel = (DefaultTableModel) getModel(); for (Object[] rowData : data) tableModel.addRow(rowData); } public synchronized boolean isListenerRegistered(XMBean mbean) { XMBeanNotificationsListener listener = listeners.get(mbean.getObjectName()); if (listener == null) return false; return listener.isRegistered(); } // Call on EDT public synchronized void loadNotifications(XMBean mbean) { XMBeanNotificationsListener listener = listeners.get(mbean.getObjectName()); emptyTable(); if (listener != null) { enabled = true; List data = listener.getData(); updateModel(data); currentListener = listener; validate(); repaint(); } else enabled = false; } // Call on EDT private void setColumnEditors() { TableColumnModel tcm = getColumnModel(); for (int i = 0; i < columnNames.length; i++) { TableColumn tc = tcm.getColumn(i); if (i == 2) { tc.setCellEditor(userDataEditor); } else { tc.setCellEditor(editor); } } } // Call on EDT public boolean isTableEditable() { return true; } // Call on EDT public synchronized void emptyTable() { DefaultTableModel model = (DefaultTableModel) getModel(); //invalidate(); while (model.getRowCount() > 0) model.removeRow(0); validate(); } // Call on EDT synchronized void updateUserDataCell(int row, int col) { Object obj = getModel().getValueAt(row, 2); if (obj instanceof UserDataCell) { UserDataCell cell = (UserDataCell) obj; if (!cell.isInited()) { if (rowMinHeight == -1) rowMinHeight = getRowHeight(row); cell.init(super.getCellRenderer(row, col), rowMinHeight); } cell.switchState(); setRowHeight(row, cell.getHeight()); if(!cell.isMaximized()) { cancelCellEditing(); //Back to simple editor. editCellAt(row, 2); } invalidate(); repaint(); } } class UserDataCellRenderer extends DefaultTableCellRenderer { Component comp; UserDataCellRenderer(Component comp) { this.comp = comp; Dimension d = comp.getPreferredSize(); if (d.getHeight() > 200) { comp.setPreferredSize(new Dimension((int) d.getWidth(), 200)); } } @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { return comp; } public Component getComponent() { return comp; } } class UserDataCell { TableCellRenderer minRenderer; UserDataCellRenderer maxRenderer; int minHeight; boolean minimized = true; boolean init = false; Object userData; UserDataCell(Object userData, Component max) { this.userData = userData; this.maxRenderer = new UserDataCellRenderer(max); } @Override public String toString() { if (userData == null) return null; if (userData.getClass().isArray()) { String name = Utils.getArrayClassName(userData.getClass().getName()); int length = Array.getLength(userData); return name + "[" + length +"]"; // NOI18N } if (userData instanceof CompositeData || userData instanceof TabularData) return userData.getClass().getName(); return userData.toString(); } boolean isInited() { return init; } void init(TableCellRenderer minRenderer, int minHeight) { this.minRenderer = minRenderer; this.minHeight = minHeight; init = true; } void switchState() { minimized = !minimized; } boolean isMaximized() { return !minimized; } void minimize() { minimized = true; } void maximize() { minimized = false; } int getHeight() { if (minimized) return minHeight; else return (int) maxRenderer.getComponent(). getPreferredSize().getHeight(); } TableCellRenderer getRenderer() { if (minimized) return minRenderer; else return maxRenderer; } } class NotifMouseListener extends MouseAdapter { @Override public void mousePressed(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { if (e.getClickCount() >= 2) { int row = XMBeanNotifications.this.getSelectedRow(); int col = XMBeanNotifications.this.getSelectedColumn(); if (col != 2) return; if (col == -1 || row == -1) return; XMBeanNotifications.this.updateUserDataCell(row, col); } } } } class UserDataCellEditor extends XTextFieldEditor { // implements javax.swing.table.TableCellEditor @Override public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column) { Object val = value; if (column == 2) { Object obj = getModel().getValueAt(row, column); if (obj instanceof UserDataCell) { UserDataCell cell = (UserDataCell) obj; if (cell.getRenderer() instanceof UserDataCellRenderer) { UserDataCellRenderer zr = (UserDataCellRenderer) cell.getRenderer(); return zr.getComponent(); } } else { Component comp = super.getTableCellEditorComponent( table, val, isSelected, row, column); textField.setEditable(false); return comp; } } return super.getTableCellEditorComponent( table, val, isSelected, row, column); } @Override public boolean stopCellEditing() { int editingRow = getEditingRow(); int editingColumn = getEditingColumn(); if (editingColumn == 2) { Object obj = getModel().getValueAt(editingRow, editingColumn); if (obj instanceof UserDataCell) { UserDataCell cell = (UserDataCell) obj; if (cell.isMaximized()) { cancelCellEditing(); return true; } } } return super.stopCellEditing(); } } class XMBeanNotificationsListener implements NotificationListener { private String[] columnNames; private XMBean mbean; private DefaultMutableTreeNode node; private volatile long received; private XMBeanNotifications notifications; private volatile boolean unregistered; private ArrayList data = new ArrayList(); public XMBeanNotificationsListener( XMBeanNotifications notifications, XMBean mbean, DefaultMutableTreeNode node, String[] columnNames) { this.notifications = notifications; this.mbean = mbean; this.node = node; this.columnNames = columnNames; register(node); } public synchronized List getData() { return data; } public synchronized void clear() { data.clear(); received = 0; } public synchronized boolean isRegistered() { return !unregistered; } public synchronized void unregister() { try { mbean.getMBeanServerConnection().removeNotificationListener( mbean.getObjectName(), this, null, null); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error removing listener", e); // NOI18N } unregistered = true; } public synchronized long getReceivedNotifications() { return received; } public synchronized void register(DefaultMutableTreeNode node) { clear(); this.node = node; try { mbean.getMBeanServerConnection().addNotificationListener( mbean.getObjectName(), this, null, null); unregistered = false; } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error adding listener", e); // NOI18N } } public synchronized void handleNotification( final Notification n, Object hb) { EventQueue.invokeLater(new Runnable() { public void run() { synchronized (XMBeanNotificationsListener.this) { try { if (unregistered) return; Date receivedDate = new Date(n.getTimeStamp()); String time = timeFormater.format(receivedDate); Object userData = n.getUserData(); Component comp = null; UserDataCell cell = null; if ((comp = XDataViewer.createNotificationViewer(userData)) != null) { XDataViewer.registerForMouseEvent(comp, mouseListener); cell = new UserDataCell(userData, comp); } Object[] rowData = { time, n.getType(), (cell == null ? userData : cell), n.getSequenceNumber(), n.getMessage(), n, n.getSource() }; received++; data.add(0, rowData); notifications.fireNotificationReceived( XMBeanNotificationsListener.this, mbean, node, rowData, received); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error handling notification", e); // NOI18N } } } }); } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XMBeanOperations.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import javax.swing.*; import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.FlowLayout; import java.awt.Component; import java.awt.event.*; import java.rmi.UnmarshalException; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.*; class XMBeanOperations extends JPanel implements ActionListener { private final static Logger LOGGER = Logger.getLogger(XMBeanOperations.class.getName()); public final static String OPERATION_INVOCATION_EVENT = "jam.xoperations.invoke.result"; // NOI18N private java.util.List notificationListenersList; private Hashtable operationEntryTable; private XMBean mbean; private MBeanInfo mbeanInfo; private MBeansTab mbeansTab; public XMBeanOperations(MBeansTab mbeansTab) { super(new GridLayout(1,1)); this.mbeansTab = mbeansTab; operationEntryTable = new Hashtable(); ArrayList l = new ArrayList(1); notificationListenersList = Collections.synchronizedList(l); } // Call on EDT public void removeOperations() { removeAll(); } // Call on EDT public void loadOperations(XMBean mbean,MBeanInfo mbeanInfo) { this.mbean = mbean; this.mbeanInfo = mbeanInfo; // add operations information MBeanOperationInfo operations[] = mbeanInfo.getOperations(); invalidate(); // remove listeners, if any Component listeners[] = getComponents(); for (int i = 0; i < listeners.length; i++) if (listeners[i] instanceof JButton) ((JButton)listeners[i]).removeActionListener(this); removeAll(); setLayout(new BorderLayout()); JButton methodButton; JLabel methodLabel; JPanel innerPanelLeft,innerPanelRight; JPanel outerPanelLeft,outerPanelRight; outerPanelLeft = new JPanel(new GridLayout(operations.length,1)); outerPanelRight = new JPanel(new GridLayout(operations.length,1)); for (int i=0;i20) { methodLabel.setText(methodLabel.getText(). substring(methodLabel.getText(). lastIndexOf(".")+1, // NOI18N methodLabel.getText().length())); } methodButton = new JButton(operations[i].getName()); methodButton.setToolTipText(operations[i].getDescription()); boolean callable = isCallable(operations[i].getSignature()); if(callable) methodButton.addActionListener(this); else methodButton.setEnabled(false); MBeanParameterInfo[] signature = operations[i].getSignature(); OperationEntry paramEntry = new OperationEntry(operations[i], callable, methodButton, this); operationEntryTable.put(methodButton, paramEntry); innerPanelRight.add(methodButton); if(signature.length==0) innerPanelRight.add(new JLabel("( )",JLabel.CENTER)); // NOI18N else innerPanelRight.add(paramEntry); outerPanelLeft.add(innerPanelLeft,BorderLayout.WEST); outerPanelRight.add(innerPanelRight,BorderLayout.CENTER); } add(outerPanelLeft,BorderLayout.WEST); add(outerPanelRight,BorderLayout.CENTER); validate(); } private boolean isCallable(MBeanParameterInfo[] signature) { for(int i = 0; i < signature.length; i++) { if(!Utils.isEditableType(signature[i].getType())) return false; } return true; } // Call on EDT public void actionPerformed(final ActionEvent e) { performInvokeRequest((JButton)e.getSource()); } void performInvokeRequest(final JButton button) { final OperationEntry entryIf = operationEntryTable.get(button); SwingWorker sw = new SwingWorker() { @Override public Object doInBackground() throws Exception { return mbean.invoke(button.getText(), entryIf.getParameters(), entryIf.getSignature()); } @Override protected void done() { try { Object result = get(); // sends result notification to upper level if // there is a return value if (entryIf.getReturnType() != null && !entryIf.getReturnType().equals(Void.TYPE.getName()) && !entryIf.getReturnType().equals(Void.class.getName())) fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result); else new ThreadDialog( button, Resources.getText("LBL_MethodSuccessfullyInvoked"), // NOI18N Resources.getText("LBL_Info"), // NOI18N JOptionPane.INFORMATION_MESSAGE).run(); } catch (Throwable t) { t = Utils.getActualException(t); LOGGER.throwing(XMBeanOperations.class.getName(), "performInvokeRequest", t); // NOI18N t = checkCNFE(t); new ThreadDialog( button, Resources.getText("LBL_ProblemInvoking") + " " + // NOI18N button.getText() + " : " + t.toString(), // NOI18N Resources.getText("LBL_Error"), // NOI18N JOptionPane.ERROR_MESSAGE).run(); } } private Throwable checkCNFE(Throwable t) { if (t instanceof UnmarshalException) { Throwable nt = t.getCause(); if (nt instanceof ClassNotFoundException) { return new RuntimeException("Cannot instantiate remote class "+nt.getMessage()); // NOI18N } } return t; } }; mbeansTab.getRequestProcessor().post(sw); } public void addOperationsListener(NotificationListener nl) { notificationListenersList.add(nl); } public void removeOperationsListener(NotificationListener nl) { notificationListenersList.remove(nl); } // Call on EDT private void fireChangedNotification( String type, Object source, Object handback) { Notification n = new Notification(type, source, 0); for(NotificationListener nl : notificationListenersList) nl.handleNotification(n, handback); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XNodeInfo.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; /** *

This class represents the user object of the nodes in the MBean tree.

* *

It encapsulates the node's info, i.e. the type of the node, the label to * be used when displaying the node in the MBean tree, the node's tool tip text * and arbitrary data which varies depending on the type of the node: an XMBean * reference for MBEAN, ATTRIBUTES, OPERATIONS and NOTIFICATIONS nodes; the * corresponding MBeanInfo for ATTRIBUTE, OPERATION and NOTIFICATION nodes; * it is not used for NONMBEAN nodes.

*/ class XNodeInfo { public static enum Type { MBEAN, NONMBEAN, ATTRIBUTES, OPERATIONS, NOTIFICATIONS, ATTRIBUTE, OPERATION, NOTIFICATION }; public XNodeInfo(Type type, Object data, String label, String tooltip) { this.type = type; this.data = data; this.label = label; this.tooltip = tooltip; } public Type getType() { return type; } public Object getData() { return data; } public String getLabel() { return label; } public String getToolTipText() { return tooltip; } @Override public String toString() { return label; } private Type type; private Object data; private String label; private String tooltip; } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XObject.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; // java import import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.*; // // java import /** * This provides a wrapper to the Object class to allow it to be displayed/manipulated as a GUI object. */ @SuppressWarnings("serial") class XObject extends JLabel { private Object object; private static boolean useHashCodeRepresentation = true; private final static Logger LOGGER = Logger.getLogger(XObject.class.getName()); public final static XObject NULL_OBJECT = new XObject("null"); // NOI18N public XObject (Object object, Icon icon) { this(object); setIcon(icon); } public XObject (Object object) { setObject(object); setHorizontalAlignment(SwingConstants.LEFT); } @Override public boolean equals(Object o) { try { if (o instanceof XObject) { return object.equals(((XObject)o).getObject()); } } catch (Throwable t) { LOGGER.log(Level.SEVERE, "Error comparing XObjects", t); // NOI18N } return false; } public Object getObject() { return object; } //if true the the object.hashcode is added to the label public static void useHashCodeRepresentation(boolean useHashCodeRepresentation) { XObject.useHashCodeRepresentation = useHashCodeRepresentation; } public static boolean hashCodeRepresentation() { return useHashCodeRepresentation; } public void setObject(Object object) { this.object = object; // if the object is not a swing component, // use default icon try { String text = null; if (object instanceof JLabel) { setIcon(((JLabel)object).getIcon()); if (getText() != null) { text = ((JLabel)object).getText(); } } else if (object instanceof JButton) { setIcon(((JButton)object).getIcon()); if (getText() != null) { text = ((JButton)object).getText(); } } else if (getText() != null) { text = object.toString(); setIcon(IconManager.DEFAULT_XOBJECT); } if (text != null) { if (useHashCodeRepresentation && (this != NULL_OBJECT)) { text = text + " ("+object.hashCode()+")"; // NOI18N } setText(text); } } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error setting XObject object", e); // NOI18N } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XOpenTypeViewer.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Component; import java.awt.Color; import java.awt.Font; import java.awt.event.*; import java.awt.Dimension; import java.util.*; import java.lang.reflect.Array; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.openmbean.*; class XOpenTypeViewer extends JPanel implements ActionListener { private final static Logger LOGGER = Logger.getLogger(XOpenTypeViewer.class.getName()); JButton prev, incr, decr, tabularPrev, tabularNext; JLabel compositeLabel, tabularLabel; JScrollPane container; XOpenTypeData current; XOpenTypeDataListener listener = new XOpenTypeDataListener(); private static final String compositeNavigationSingle = Resources.getText("LBL_MBeansTab.compositeNavigationSingle"); // NOI18N private static final String tabularNavigationSingle = Resources.getText("LBL_MBeansTab.tabularNavigationSingle"); // NOI18N private static TableCellEditor editor = new Utils.ReadOnlyTableCellEditor(new JTextField()); class XOpenTypeDataListener extends MouseAdapter { XOpenTypeDataListener() { } @Override public void mousePressed(MouseEvent e) { if(e.getButton() == MouseEvent.BUTTON1) { if(e.getClickCount() >= 2) { XOpenTypeData elem = getSelectedViewedOpenType(); if(elem != null) { try { elem.viewed(XOpenTypeViewer.this); }catch(Exception ex) { //Nothing to change, the element //can't be displayed } } } } } private XOpenTypeData getSelectedViewedOpenType() { int row = XOpenTypeViewer.this.current.getSelectedRow(); int col = XOpenTypeViewer.this.current.getSelectedColumn(); Object elem = XOpenTypeViewer.this.current.getModel().getValueAt(row, col); if(elem instanceof XOpenTypeData) return (XOpenTypeData) elem; else return null; } } static interface Navigatable { public void incrElement(); public void decrElement(); public boolean canDecrement(); public boolean canIncrement(); public int getElementCount(); public int getSelectedElementIndex(); } static interface XViewedTabularData extends Navigatable { } static interface XViewedArrayData extends Navigatable { } static abstract class XOpenTypeData extends JTable { XOpenTypeData parent; private Color defaultColor; protected int col1Width = -1; protected int col2Width = -1; private boolean init; private Font normalFont, boldFont; protected XOpenTypeData(XOpenTypeData parent) { this.parent = parent; } public XOpenTypeData getViewedParent() { return parent; } public String getToolTip(int row, int col) { if(col == XTable.VALUE_COLUMN) { Object value = getModel().getValueAt(row, col); if (value != null) { if(isClickableElement(value)) return Resources.getText("LBL_DoubleClickToVisualize") // NOI18N + ". " + value.toString(); // NOI18N else return value.toString(); } } return null; } @Override public TableCellRenderer getCellRenderer(int row, int column) { DefaultTableCellRenderer tcr = (DefaultTableCellRenderer)super.getCellRenderer(row,column); tcr.setToolTipText(getToolTip(row,column)); return tcr; } public void renderKey(String key, Component comp) { comp.setFont(normalFont); } @Override public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { Component comp = super.prepareRenderer(renderer, row, column); if (normalFont == null) { normalFont = comp.getFont(); boldFont = normalFont.deriveFont(Font.BOLD); } Object o = ((DefaultTableModel) getModel()).getValueAt(row, column); if (column == 0) { String key = o.toString(); renderKey(key, comp); } else { if (isClickableElement(o)) { comp.setFont(boldFont); } else { comp.setFont(normalFont); } } return comp; } protected boolean isClickableElement(Object obj) { if (obj instanceof XOpenTypeData) { if (obj instanceof Navigatable) { return (((Navigatable) obj).getElementCount() != 0); } else { return (obj instanceof XCompositeData); } } return false; } protected void updateColumnWidth() { if (!init) { TableColumnModel colModel = getColumnModel(); if (col2Width == -1) { col1Width = col1Width * 7; if (col1Width < getPreferredScrollableViewportSize().getWidth()) { col1Width = (int) getPreferredScrollableViewportSize().getWidth(); } colModel.getColumn(0).setPreferredWidth(col1Width); init = true; return; } col1Width = (col1Width * 7) + 7; col1Width = Math.max(col1Width, 70); col2Width = (col2Width * 7) + 7; if (col1Width + col2Width < getPreferredScrollableViewportSize().getWidth()) { col2Width = (int) getPreferredScrollableViewportSize().getWidth() - col1Width; } colModel.getColumn(0).setPreferredWidth(col1Width); colModel.getColumn(1).setPreferredWidth(col2Width); init = true; } } public abstract void viewed(XOpenTypeViewer viewer) throws Exception; protected void initTable(String[] columnNames) { setRowSelectionAllowed(false); setColumnSelectionAllowed(false); getTableHeader().setReorderingAllowed(false); ((DefaultTableModel) getModel()).setColumnIdentifiers(columnNames); for (Enumeration e = getColumnModel().getColumns(); e.hasMoreElements();) { TableColumn tc = e.nextElement(); tc.setCellEditor(editor); } addKeyListener(new Utils.CopyKeyAdapter()); setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); setPreferredScrollableViewportSize(new Dimension(350, 200)); } protected void emptyTable() { invalidate(); while (getModel().getRowCount()>0) ((DefaultTableModel) getModel()).removeRow(0); validate(); } @Override public void setValueAt(Object value, int row, int col) { } } static class TabularDataComparator implements Comparator { private final List indexNames; public TabularDataComparator(TabularType type) { indexNames = type.getIndexNames(); } @SuppressWarnings("unchecked") public int compare(CompositeData o1, CompositeData o2) { for (String key : indexNames) { Object c1 = o1.get(key); Object c2 = o2.get(key); if (c1 instanceof Comparable && c2 instanceof Comparable) { int result = ((Comparable) c1).compareTo(c2); if (result != 0) return result; } } return 0; } } static class XTabularData extends XCompositeData implements XViewedTabularData { final TabularData tabular; final TabularType type; int currentIndex = 0; final Object[] elements; final int size; private Font normalFont, italicFont; @SuppressWarnings("unchecked") public XTabularData(XOpenTypeData parent, TabularData tabular) { super(parent, accessFirstElement(tabular)); this.tabular = tabular; type = tabular.getTabularType(); size = tabular.values().size(); if (size > 0) { // Order tabular data elements using index names List data = new ArrayList( (Collection) tabular.values()); Collections.sort(data, new TabularDataComparator(type)); elements = data.toArray(); loadCompositeData((CompositeData) elements[0]); } else { elements = new Object[0]; } } private static CompositeData accessFirstElement(TabularData tabular) { if(tabular.values().size() == 0) return null; return (CompositeData) tabular.values().toArray()[0]; } @Override public void renderKey(String key, Component comp) { if (normalFont == null) { normalFont = comp.getFont(); italicFont = normalFont.deriveFont(Font.ITALIC); } for(Object k : type.getIndexNames()) { if(key.equals(k)) comp.setFont(italicFont); } } public int getElementCount() { return size; } public int getSelectedElementIndex() { return currentIndex; } public void incrElement() { currentIndex++; loadCompositeData((CompositeData)elements[currentIndex]); } public void decrElement() { currentIndex--; loadCompositeData((CompositeData)elements[currentIndex]); } public boolean canDecrement() { if(currentIndex == 0) return false; else return true; } public boolean canIncrement(){ if(size == 0 || currentIndex == size -1) return false; else return true; } @Override public String toString() { return type == null ? "" : type.getDescription(); // NOI18N } } static class XCompositeData extends XOpenTypeData { protected final String[] columnNames = { Resources.getText("LBL_Name"), Resources.getText("LBL_Value") // NOI18N }; CompositeData composite; public XCompositeData() { super(null); initTable(columnNames); } //In sync with array, no init table. public XCompositeData(XOpenTypeData parent) { super(parent); } public XCompositeData(XOpenTypeData parent, CompositeData composite) { super(parent); initTable(columnNames); if(composite != null) { this.composite = composite; loadCompositeData(composite); } } public void viewed(XOpenTypeViewer viewer) throws Exception { viewer.setOpenType(this); updateColumnWidth(); } @Override public String toString() { return composite == null ? "" : // NOI18N composite.getCompositeType().getTypeName(); } protected Object formatKey(String key) { return key; } public String getToolTip(int row, int col) { if (col == XTable.NAME_COLUMN && composite != null) { String val = getModel().getValueAt(row,col).toString(); return composite.getCompositeType().getDescription(val); } return super.getToolTip(row, col); } private void load(CompositeData data) { CompositeType type = data.getCompositeType(); Set keys = type.keySet(); Iterator it = keys.iterator(); Object[] rowData = new Object[2]; while (it.hasNext()) { String key = (String) it.next(); Object val = data.get(key); rowData[0] = formatKey(key); if (val == null) { rowData[1] = ""; // NOI18N } else { OpenType openType = type.getType(key); if (openType instanceof CompositeType) { rowData[1] = new XCompositeData(this, (CompositeData) val); } else if (openType instanceof ArrayType) { rowData[1] = new XArrayData(this, (ArrayType) openType, val); } else if (openType instanceof SimpleType) { rowData[1] = val; } else if (openType instanceof TabularType) { rowData[1] = new XTabularData(this, (TabularData) val); } } // Update column width String str = null; if (rowData[0] != null) { str = rowData[0].toString(); if (str.length() > col1Width) { col1Width = str.length(); } } if (rowData[1] != null) { str = rowData[1].toString(); if (str.length() > col2Width) { col2Width = str.length(); } } ((DefaultTableModel) getModel()).addRow(rowData); } } protected void loadCompositeData(CompositeData data) { composite = data; emptyTable(); load(data); DefaultTableModel tableModel = (DefaultTableModel) getModel(); tableModel.newDataAvailable(new TableModelEvent(tableModel)); } } static class XArrayData extends XCompositeData implements XViewedArrayData { private int dimension; private int size; private OpenType elemType; private Object val; private boolean isCompositeType; private boolean isTabularType; private int currentIndex; private CompositeData[] elements; private final String[] arrayColumns = {Resources.getText("LBL_Value")}; // NOI18N private Font normalFont, boldFont; XArrayData(XOpenTypeData parent, ArrayType type, Object val) { this(parent, type.getDimension(), type.getElementOpenType(), val); } XArrayData(XOpenTypeData parent, int dimension, OpenType elemType, Object val) { super(parent); this.dimension = dimension; this.elemType = elemType; this.val = val; String[] columns = null; if (dimension > 1) return; isCompositeType = (elemType instanceof CompositeType); isTabularType = (elemType instanceof TabularType); columns = isCompositeType ? columnNames : arrayColumns; initTable(columns); loadArray(); } @Override public void viewed(XOpenTypeViewer viewer) throws Exception { if (size == 0) throw new Exception(Resources.getText("LBL_EmptyArray")); // NOI18N if (dimension > 1) throw new Exception(Resources.getText("LBL_DimensionIsNotSupported") // NOI18N + ": " + dimension); // NOI18N super.viewed(viewer); } public int getElementCount() { return size; } public int getSelectedElementIndex() { return currentIndex; } @Override public void renderKey(String key, Component comp) { if (normalFont == null) { normalFont = comp.getFont(); boldFont = normalFont.deriveFont(Font.BOLD); } if (isTabularType) { comp.setFont(boldFont); } } public void incrElement() { currentIndex++; loadCompositeData(elements[currentIndex]); } public void decrElement() { currentIndex--; loadCompositeData(elements[currentIndex]); } public boolean canDecrement() { if (isCompositeType && currentIndex > 0) { return true; } return false; } public boolean canIncrement() { if (isCompositeType && currentIndex < size - 1) { return true; } return false; } private void loadArray() { if (isCompositeType) { elements = (CompositeData[]) val; size = elements.length; if (size != 0) { loadCompositeData(elements[0]); } } else { load(); } } private void load() { Object[] rowData = new Object[1]; size = Array.getLength(val); for (int i = 0; i < size; i++) { rowData[0] = isTabularType ? new XTabularData(this, (TabularData) Array.get(val, i)) : Array.get(val, i); String str = rowData[0].toString(); if (str.length() > col1Width) { col1Width = str.length(); } ((DefaultTableModel) getModel()).addRow(rowData); } } @Override public String toString() { if (dimension > 1) { return Resources.getText("LBL_DimensionIsNotSupported") + // NOI18N ": " + dimension; // NOI18N } else { return elemType.getTypeName() + "[" + size + "]"; // NOI18N } } } /** * The supplied value is viewable iff: * - it's a CompositeData/TabularData, or * - it's a non-empty array of CompositeData/TabularData, or * - it's a non-empty Collection of CompositeData/TabularData. */ public static boolean isViewableValue(Object value) { // Check for CompositeData/TabularData // if (value instanceof CompositeData || value instanceof TabularData) { return true; } // Check for non-empty array of CompositeData/TabularData // if (value instanceof CompositeData[] || value instanceof TabularData[]) { return Array.getLength(value) > 0; } // Check for non-empty Collection of CompositeData/TabularData // if (value instanceof Collection) { Collection c = (Collection) value; if (c.isEmpty()) { // Empty Collections are not viewable // return false; } else { // Only Collections of CompositeData/TabularData are viewable // return Utils.isUniformCollection(c, CompositeData.class) || Utils.isUniformCollection(c, TabularData.class); } } return false; } public static Component loadOpenType(Object value) { Component comp = null; if(isViewableValue(value)) { XOpenTypeViewer open = new XOpenTypeViewer(value); comp = open; } return comp; } private XOpenTypeViewer(Object value) { XOpenTypeData comp = null; if (value instanceof CompositeData) { comp = new XCompositeData(null, (CompositeData) value); } else if (value instanceof TabularData) { comp = new XTabularData(null, (TabularData) value); } else if (value instanceof CompositeData[]) { CompositeData cda[] = (CompositeData[]) value; CompositeType ct = cda[0].getCompositeType(); comp = new XArrayData(null, 1, ct, cda); } else if (value instanceof TabularData[]) { TabularData tda[] = (TabularData[]) value; TabularType tt = tda[0].getTabularType(); comp = new XArrayData(null, 1, tt, tda); } else if (value instanceof Collection) { // At this point we know 'value' is a uniform collection, either // Collection or Collection, because // isViewableValue() has been called before calling the private // XOpenTypeViewer() constructor. // Object e = ((Collection) value).iterator().next(); if (e instanceof CompositeData) { Collection cdc = (Collection) value; CompositeData cda[] = cdc.toArray(new CompositeData[0]); CompositeType ct = cda[0].getCompositeType(); comp = new XArrayData(null, 1, ct, cda); } else if (e instanceof TabularData) { Collection tdc = (Collection) value; TabularData tda[] = tdc.toArray(new TabularData[0]); TabularType tt = tda[0].getTabularType(); comp = new XArrayData(null, 1, tt, tda); } } setupDisplay(comp); try { comp.viewed(this); } catch (Exception e) { // Nothing to change, the element can't be displayed LOGGER.log(Level.SEVERE, "Exception viewing openType", e); // NOI18N } } void setOpenType(XOpenTypeData data) { if (current != null) { current.removeMouseListener(listener); } current = data; // Enable/Disable the previous (<<) button if (current.getViewedParent() == null) { prev.setEnabled(false); } else { prev.setEnabled(true); } // Set the listener to handle double-click mouse events current.addMouseListener(listener); // Enable/Disable the tabular buttons if (!(data instanceof XViewedTabularData)) { tabularPrev.setEnabled(false); tabularNext.setEnabled(false); tabularLabel.setText(tabularNavigationSingle); tabularLabel.setEnabled(false); } else { XViewedTabularData tabular = (XViewedTabularData) data; tabularNext.setEnabled(tabular.canIncrement()); tabularPrev.setEnabled(tabular.canDecrement()); boolean hasMoreThanOneElement = tabular.canIncrement() || tabular.canDecrement(); if (hasMoreThanOneElement) { tabularLabel.setText( Resources.getText("LBL_MBeansTab.tabularNavigationMultiple", // NOI18N String.format("%d", tabular.getSelectedElementIndex() + 1), // NOI18N String.format("%d", tabular.getElementCount()))); // NOI18N } else { tabularLabel.setText(tabularNavigationSingle); } tabularLabel.setEnabled(hasMoreThanOneElement); } // Enable/Disable the composite buttons if (!(data instanceof XViewedArrayData)) { incr.setEnabled(false); decr.setEnabled(false); compositeLabel.setText(compositeNavigationSingle); compositeLabel.setEnabled(false); } else { XViewedArrayData array = (XViewedArrayData) data; incr.setEnabled(array.canIncrement()); decr.setEnabled(array.canDecrement()); boolean hasMoreThanOneElement = array.canIncrement() || array.canDecrement(); if (hasMoreThanOneElement) { compositeLabel.setText( Resources.getText("LBL_MBeansTab.compositeNavigationMultiple", // NOI18N String.format("%d", array.getSelectedElementIndex() + 1), // NOI18N String.format("%d", array.getElementCount()))); // NOI18N } else { compositeLabel.setText(compositeNavigationSingle); } compositeLabel.setEnabled(hasMoreThanOneElement); } container.invalidate(); container.setViewportView(current); container.validate(); } public void actionPerformed(ActionEvent event) { if (event.getSource() instanceof JButton) { JButton b = (JButton) event.getSource(); if (b == prev) { XOpenTypeData parent = current.getViewedParent(); try { parent.viewed(this); } catch (Exception e) { //Nothing to change, the element can't be displayed } } else if (b == incr) { ((XViewedArrayData) current).incrElement(); try { current.viewed(this); } catch (Exception e) { //Nothing to change, the element can't be displayed } } else if (b == decr) { ((XViewedArrayData) current).decrElement(); try { current.viewed(this); } catch (Exception e) { //Nothing to change, the element can't be displayed } } else if (b == tabularNext) { ((XViewedTabularData) current).incrElement(); try { current.viewed(this); } catch (Exception e) { //Nothing to change, the element can't be displayed } } else if (b == tabularPrev) { ((XViewedTabularData) current).decrElement(); try { current.viewed(this); } catch (Exception e) { //Nothing to change, the element can't be displayed } } } } private void setupDisplay(XOpenTypeData data) { setBackground(Color.white); container = new JScrollPane(data, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT)); tabularPrev = new JButton(Resources.getText("LBL_<")); // NOI18N tabularNext = new JButton(Resources.getText("LBL_>")); // NOI18N JPanel tabularButtons = new JPanel(new FlowLayout(FlowLayout.LEFT)); tabularButtons.add(tabularPrev); tabularPrev.addActionListener(this); tabularLabel = new JLabel(tabularNavigationSingle); tabularLabel.setEnabled(false); tabularButtons.add(tabularLabel); tabularButtons.add(tabularNext); tabularNext.addActionListener(this); tabularButtons.setBackground(Color.white); prev = new JButton(Resources.getText("LBL_<<")); // NOI18N prev.addActionListener(this); buttons.add(prev); incr = new JButton(Resources.getText("LBL_>")); // NOI18N incr.addActionListener(this); decr = new JButton(Resources.getText("LBL_<")); // NOI18N decr.addActionListener(this); JPanel array = new JPanel(); array.setBackground(Color.white); array.add(decr); compositeLabel = new JLabel(compositeNavigationSingle); compositeLabel.setEnabled(false); array.add(compositeLabel); array.add(incr); buttons.add(array); setLayout(new BorderLayout()); buttons.setBackground(Color.white); JPanel navigationPanel = new JPanel(new BorderLayout()); navigationPanel.setBackground(Color.white); navigationPanel.add(tabularButtons, BorderLayout.NORTH); navigationPanel.add(buttons, BorderLayout.WEST); add(navigationPanel, BorderLayout.NORTH); add(container, BorderLayout.CENTER); Dimension d = new Dimension((int)container.getPreferredSize(). getWidth() + 20, (int)container.getPreferredSize(). getHeight() + 20); setPreferredSize(d); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XPlotter.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import javax.swing.JTable; @SuppressWarnings("serial") class XPlotter extends Plotter { JTable table; public XPlotter(JTable table, Plotter.Unit unit) { super(unit,0,false); this.table = table; } @Override public void addValues(long time, long... values) { super.addValues(time, values); table.repaint(); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XPlottingViewer.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashMap; import java.util.Iterator; import java.util.logging.Logger; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.Timer; @SuppressWarnings("serial") class XPlottingViewer extends PlotterPanel implements ActionListener { private final static Logger LOGGER = Logger.getLogger(XPlottingViewer.class.getName()); // TODO: Make number of decimal places customizable private static final int PLOTTER_DECIMALS = 4; private JButton plotButton; // The plotter cache holds Plotter instances for the various attributes private static HashMap plotterCache = new HashMap(); private static HashMap timerCache = new HashMap(); private MBeansTab tab; private XMBean mbean; private String attributeName; private String key; private JTable table; private XPlottingViewer(String key, XMBean mbean, String attributeName, Object value, JTable table, MBeansTab tab) { super(null); this.tab = tab; this.key = key; this.mbean = mbean; this.table = table; this.attributeName = attributeName; setupDisplay(createPlotter(mbean, attributeName, key, table)); } static void dispose(MBeansTab tab) { Iterator it = plotterCache.keySet().iterator(); while(it.hasNext()) { String key = (String) it.next(); if(key.startsWith(String.valueOf(tab.hashCode()))) { it.remove(); } } //plotterCache.clear(); it = timerCache.keySet().iterator(); while(it.hasNext()) { String key = (String) it.next(); if(key.startsWith(String.valueOf(tab.hashCode()))) { Timer t = timerCache.get(key); t.stop(); it.remove(); } } } public static boolean isViewableValue(Object value) { return (value instanceof Number); } // Fired by dbl click public static Component loadPlotting( XMBean mbean, String attributeName, Object value, JTable table, MBeansTab tab) { Component comp = null; if (isViewableValue(value)) { String key = String.valueOf(tab.hashCode()) + " " + // NOI18N String.valueOf(mbean.hashCode()) + " " + // NOI18N mbean.getObjectName().getCanonicalName() + attributeName; XPlottingViewer p = plotterCache.get(key); if (p == null) { p = new XPlottingViewer(key, mbean, attributeName, value, table, tab); plotterCache.put(key, p); } comp = p; } return comp; } @Override public void actionPerformed(ActionEvent evt) { plotterCache.remove(key); Timer t = timerCache.remove(key); t.stop(); ((XMBeanAttributes) table).collapse(attributeName, this); } // Create plotter instance public Plotter createPlotter(final XMBean xmbean, final String attributeName, String key, JTable table) { final Plotter p = new XPlotter(table, Plotter.Unit.NONE) { Dimension prefSize = new Dimension(400, 170); @Override public Dimension getPreferredSize() { return prefSize; } @Override public Dimension getMinimumSize() { return prefSize; } }; p.createSequence(attributeName, attributeName, null, true); Timer timer = new Timer(tab.getUpdateInterval(), new ActionListener() { public void actionPerformed(ActionEvent e) { intervalElapsed(p); } }); timer.setCoalesce(true); timer.setInitialDelay(0); timer.start(); timerCache.put(key, timer); return p; } void intervalElapsed(final Plotter p) { tab.getRequestProcessor().post(new Runnable() { public void run() { try { Number n = (Number) mbean.getCachedMBeanServerConnection(). getAttribute( mbean.getObjectName(), attributeName); long v; if (n instanceof Float || n instanceof Double) { p.setDecimals(PLOTTER_DECIMALS); double d = (n instanceof Float) ? (Float) n : (Double) n; v = Math.round(d * Math.pow(10.0, PLOTTER_DECIMALS)); } else { v = n.longValue(); } p.addValues(System.currentTimeMillis(), v); } catch (Exception e) { LOGGER.throwing(XPlottingViewer.class.getName(), "intervalElapsed", e); // NOI18N } } }); } // Create Plotter display private void setupDisplay(Plotter p) { final JPanel buttonPanel = new JPanel(); final GridBagLayout gbl = new GridBagLayout(); buttonPanel.setLayout(gbl); setLayout(new BorderLayout()); plotButton = new JButton(Resources.getText("LBL_DiscardChart")); // NOI18N plotButton.addActionListener(this); plotButton.setEnabled(true); GridBagConstraints buttonConstraints = new GridBagConstraints(); buttonConstraints.gridx = 0; buttonConstraints.gridy = 0; buttonConstraints.fill = GridBagConstraints.VERTICAL; buttonConstraints.anchor = GridBagConstraints.CENTER; gbl.setConstraints(plotButton, buttonConstraints); buttonPanel.add(plotButton); if (attributeName != null && attributeName.length()!=0) { final JPanel plotterLabelPanel = new JPanel(); final JLabel atlabel = new JLabel(attributeName); final GridBagLayout gbl2 = new GridBagLayout(); plotterLabelPanel.setLayout(gbl2); final GridBagConstraints labelConstraints = new GridBagConstraints(); labelConstraints.gridx = 0; labelConstraints.gridy = 0; labelConstraints.fill = GridBagConstraints.VERTICAL; labelConstraints.anchor = GridBagConstraints.CENTER; labelConstraints.ipady = 10; gbl2.setConstraints(atlabel, labelConstraints); plotterLabelPanel.add(atlabel); add(plotterLabelPanel, BorderLayout.NORTH); } setPlotter(p); add(buttonPanel, BorderLayout.SOUTH); repaint(); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XSheet.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.*; import java.awt.event.*; import java.io.*; import javax.management.*; import javax.swing.*; import javax.swing.tree.*; import org.graalvm.visualvm.modules.mbeans.XNodeInfo.Type; import java.util.logging.Level; import java.util.logging.Logger; import static org.graalvm.visualvm.modules.mbeans.Resources.*; @SuppressWarnings("serial") class XSheet extends JPanel implements ActionListener, NotificationListener { private final static Logger LOGGER = Logger.getLogger(XSheet.class.getName()); private JPanel topPanelAttributes; private JPanel topPanelOperations; private JPanel topPanelNotifications; private JPanel topPanelMetadata; // Node being currently displayed private volatile DefaultMutableTreeNode currentNode; // MBean being currently displayed private volatile XMBean mbean; // XMBeanAttributes container private XMBeanAttributes mbeanAttributes; // XMBeanOperations container private XMBeanOperations mbeanOperations; // XMBeanNotifications container private XMBeanNotifications mbeanNotifications; // XMBeanInfo container private XMBeanInfo mbeanInfo; // Refresh JButton (mbean attributes case) private JButton refreshButton; // Subscribe/Unsubscribe/Clear JButton (mbean notifications case) private JButton clearButton, subscribeButton, unsubscribeButton; // Reference to MBeans tab private MBeansTab mbeansTab; public XSheet(MBeansTab mbeansTab) { this.mbeansTab = mbeansTab; setupScreen(); } public JPanel getAttributes() { return topPanelAttributes; } public JPanel getOperations() { return topPanelOperations; } public JPanel getNotifications() { return topPanelNotifications; } public JPanel getMetadata() { return topPanelMetadata; } public void dispose() { clearNotifications(); clear(); XDataViewer.dispose(mbeansTab); mbeanNotifications.dispose(); displayEmptyNode(); } private void setupScreen() { setLayout(new BorderLayout()); setBorder(BorderFactory.createLineBorder(Color.GRAY)); // create attributes panel topPanelAttributes = new JPanel(); topPanelAttributes.setLayout(new BorderLayout()); // create operations panel topPanelOperations = new JPanel(); topPanelOperations.setLayout(new BorderLayout()); // create notifications panel topPanelNotifications = new JPanel(); topPanelNotifications.setLayout(new BorderLayout()); // create metadata panel topPanelMetadata = new JPanel(); topPanelMetadata.setLayout(new BorderLayout()); // create the refresh button String refreshButtonKey = "LBL_MBeansTab.refreshAttributesButton"; // NOI18N refreshButton = new JButton(getText(refreshButtonKey)); refreshButton.setMnemonic(getMnemonicInt(refreshButtonKey)); refreshButton.setToolTipText(getText(refreshButtonKey + ".toolTip")); // NOI18N refreshButton.addActionListener(this); // create the clear button String clearButtonKey = "LBL_MBeansTab.clearNotificationsButton"; // NOI18N clearButton = new JButton(getText(clearButtonKey)); clearButton.setMnemonic(getMnemonicInt(clearButtonKey)); clearButton.setToolTipText(getText(clearButtonKey + ".toolTip")); // NOI18N clearButton.addActionListener(this); // create the subscribe button String subscribeButtonKey = "LBL_MBeansTab.subscribeNotificationsButton"; // NOI18N subscribeButton = new JButton(getText(subscribeButtonKey)); subscribeButton.setMnemonic(getMnemonicInt(subscribeButtonKey)); subscribeButton.setToolTipText(getText(subscribeButtonKey + ".toolTip")); // NOI18N subscribeButton.addActionListener(this); // create the unsubscribe button String unsubscribeButtonKey = "LBL_MBeansTab.unsubscribeNotificationsButton"; // NOI18N unsubscribeButton = new JButton(getText(unsubscribeButtonKey)); unsubscribeButton.setMnemonic(getMnemonicInt(unsubscribeButtonKey)); unsubscribeButton.setToolTipText(getText(unsubscribeButtonKey + ".toolTip")); // NOI18N unsubscribeButton.addActionListener(this); // create XMBeanAttributes container mbeanAttributes = new XMBeanAttributes(mbeansTab); // create XMBeanOperations container mbeanOperations = new XMBeanOperations(mbeansTab); mbeanOperations.addOperationsListener(this); // create XMBeanNotifications container mbeanNotifications = new XMBeanNotifications(); mbeanNotifications.addNotificationsListener(this); // create XMBeanInfo container mbeanInfo = new XMBeanInfo(); } private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) { return (cn == n); } // Call on EDT private void showErrorDialog(Object message, String title) { new ThreadDialog(this, message, title, JOptionPane.ERROR_MESSAGE).run(); } public boolean isMBeanNode(DefaultMutableTreeNode node) { Object userObject = node.getUserObject(); if (userObject instanceof XNodeInfo) { XNodeInfo uo = (XNodeInfo) userObject; return uo.getType().equals(Type.MBEAN); } return false; } // Call on EDT public synchronized void displayNode(DefaultMutableTreeNode node) { clear(); displayEmptyNode(); if (node == null) { return; } currentNode = node; clearNotifications(); Object userObject = node.getUserObject(); if (userObject instanceof XNodeInfo) { XNodeInfo uo = (XNodeInfo) userObject; switch (uo.getType()) { case MBEAN: displayMBeanAttributesNode(node); displayMBeanOperationsNode(node); displayMBeanNotificationsNode(node); displayMBeanMetadataNode(node); break; case NONMBEAN: displayEmptyNode(); break; default: displayEmptyNode(); break; } } else { displayEmptyNode(); } } // Call on EDT private void displayMBeanMetadataNode(final DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.MBEAN)) { return; } mbean = (XMBean) uo.getData(); final XMBean xmb = mbean; SwingWorker sw = new SwingWorker() { @Override public MBeanInfo doInBackground() throws InstanceNotFoundException, IntrospectionException, ReflectionException, IOException { return xmb.getMBeanInfo(); } @Override protected void done() { try { MBeanInfo mbi = get(); if (xmb == mbean && mbi != null) { if (!isSelectedNode(node, currentNode)) return; mbeanInfo.loadMBeanInfo(xmb, mbi); topPanelMetadata.invalidate(); topPanelMetadata.removeAll(); mbeansTab.getButtonAt(3).setEnabled(true); JPanel mainPanelMetadata = new JPanel(); mainPanelMetadata.setLayout(new BorderLayout()); mainPanelMetadata.add(mbeanInfo, BorderLayout.CENTER); topPanelMetadata.add(mainPanelMetadata, BorderLayout.CENTER); JPanel southPanelMetadata = new JPanel(); topPanelMetadata.add(southPanelMetadata, BorderLayout.SOUTH); topPanelMetadata.validate(); repaint(); } } catch (Exception e) { Throwable t = Utils.getActualException(e); LOGGER.log(Level.SEVERE, "Couldn't get MBeanInfo for MBean [" + // NOI18N xmb.getObjectName() + "]", t); // NOI18N showErrorDialog(t.toString(), Resources.getText("LBL_ProblemDisplayingMBean")); // NOI18N } } }; mbeansTab.getRequestProcessor().post(sw); } // Call on EDT private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.MBEAN)) { return; } mbean = (XMBean) uo.getData(); final XMBean xmb = mbean; SwingWorker sw = new SwingWorker() { @Override public MBeanInfo doInBackground() throws InstanceNotFoundException, IntrospectionException, ReflectionException, IOException { MBeanInfo mbi = xmb.getMBeanInfo(); return mbi; } @Override protected void done() { try { MBeanInfo mbi = get(); mbeanAttributes.loadAttributes(xmb, mbi); if (xmb == mbean && mbi != null && mbi.getAttributes() != null && mbi.getAttributes().length > 0) { if (!isSelectedNode(node, currentNode)) return; topPanelAttributes.invalidate(); topPanelAttributes.removeAll(); mbeansTab.getButtonAt(0).setEnabled(true); JPanel borderPanel = new JPanel(new BorderLayout()); borderPanel.setBorder(BorderFactory.createTitledBorder( Resources.getText("LBL_AttributeValues"))); // NOI18N borderPanel.add(new JScrollPane(mbeanAttributes)); JPanel mainPanelAttributes = new JPanel(); mainPanelAttributes.setLayout(new BorderLayout()); mainPanelAttributes.add(borderPanel, BorderLayout.CENTER); topPanelAttributes.add(mainPanelAttributes, BorderLayout.CENTER); // add the refresh button to the south panel JPanel southPanelAttributes = new JPanel(); southPanelAttributes.add(refreshButton, BorderLayout.SOUTH); southPanelAttributes.setVisible(true); refreshButton.setEnabled(true); topPanelAttributes.add(southPanelAttributes, BorderLayout.SOUTH); topPanelAttributes.validate(); repaint(); } } catch (Exception e) { Throwable t = Utils.getActualException(e); LOGGER.log(Level.SEVERE, "Problem displaying MBean " + // NOI18N "attributes for MBean [" + // NOI18N xmb.getObjectName() + "]", t); // NOI18N showErrorDialog(t.toString(), Resources.getText("LBL_ProblemDisplayingMBean")); // NOI18N } } }; mbeansTab.getRequestProcessor().post(sw); } // Call on EDT private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.MBEAN)) { return; } mbean = (XMBean) uo.getData(); final XMBean xmb = mbean; SwingWorker sw = new SwingWorker() { @Override public MBeanInfo doInBackground() throws InstanceNotFoundException, IntrospectionException, ReflectionException, IOException { return xmb.getMBeanInfo(); } @Override protected void done() { try { MBeanInfo mbi = get(); if (xmb == mbean && mbi != null && mbi.getOperations() != null && mbi.getOperations().length > 0) { if (!isSelectedNode(node, currentNode)) return; mbeanOperations.loadOperations(xmb, mbi); topPanelOperations.invalidate(); topPanelOperations.removeAll(); mbeansTab.getButtonAt(1).setEnabled(true); JPanel borderPanel = new JPanel(new BorderLayout()); borderPanel.setBorder(BorderFactory.createTitledBorder( Resources.getText("LBL_OperationInvocation"))); // NOI18N borderPanel.add(new JScrollPane(mbeanOperations)); JPanel mainPanelOperations = new JPanel(); mainPanelOperations.setLayout(new BorderLayout()); mainPanelOperations.add(borderPanel, BorderLayout.CENTER); topPanelOperations.add(mainPanelOperations, BorderLayout.CENTER); JPanel southPanelOperations = new JPanel(); topPanelOperations.add(southPanelOperations, BorderLayout.SOUTH); topPanelOperations.validate(); repaint(); } } catch (Exception e) { Throwable t = Utils.getActualException(e); LOGGER.log(Level.SEVERE, "Problem displaying MBean " + // NOI18N "operations for MBean [" + // NOI18N xmb.getObjectName() + "]", t); // NOI18N showErrorDialog(t.toString(), Resources.getText("LBL_ProblemDisplayingMBean")); // NOI18N } } }; mbeansTab.getRequestProcessor().post(sw); } // Call on EDT private void displayMBeanNotificationsNode(final DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.MBEAN)) { return; } mbean = (XMBean) uo.getData(); final XMBean xmb = mbean; SwingWorker sw = new SwingWorker() { @Override public Boolean doInBackground() { return xmb.isBroadcaster(); } @Override protected void done() { try { Boolean isBroadcaster = get(); if (xmb == mbean && isBroadcaster != null && isBroadcaster.booleanValue()) { if (!isSelectedNode(node, currentNode)) return; mbeanNotifications.loadNotifications(xmb); updateNotifications(); topPanelNotifications.invalidate(); topPanelNotifications.removeAll(); mbeansTab.getButtonAt(2).setEnabled(true); JPanel borderPanel = new JPanel(new BorderLayout()); borderPanel.setBorder(BorderFactory.createTitledBorder( Resources.getText("LBL_NotificationBuffer"))); // NOI18N borderPanel.add(new JScrollPane(mbeanNotifications)); JPanel mainPanelNotifications = new JPanel(); mainPanelNotifications.setLayout(new BorderLayout()); mainPanelNotifications.add(borderPanel, BorderLayout.CENTER); topPanelNotifications.add(mainPanelNotifications, BorderLayout.CENTER); // add the subscribe/unsubscribe/clear buttons to the south panel JPanel southPanelNotifications = new JPanel(); southPanelNotifications.add(subscribeButton, BorderLayout.WEST); southPanelNotifications.add(unsubscribeButton, BorderLayout.CENTER); southPanelNotifications.add(clearButton, BorderLayout.EAST); southPanelNotifications.setVisible(true); subscribeButton.setEnabled(true); unsubscribeButton.setEnabled(true); clearButton.setEnabled(true); topPanelNotifications.add(southPanelNotifications, BorderLayout.SOUTH); topPanelNotifications.validate(); repaint(); } } catch (Exception e) { Throwable t = Utils.getActualException(e); LOGGER.log(Level.SEVERE, "Problem displaying MBean " + // NOI18N "notifications for MBean [" + // NOI18N xmb.getObjectName() + "]", t); // NOI18N showErrorDialog(t.toString(), Resources.getText("LBL_ProblemDisplayingMBean")); // NOI18N } } }; mbeansTab.getRequestProcessor().post(sw); } // Call on EDT private void displayEmptyNode() { invalidate(); topPanelAttributes.invalidate(); topPanelAttributes.removeAll(); topPanelAttributes.validate(); topPanelAttributes.repaint(); topPanelOperations.invalidate(); topPanelOperations.removeAll(); topPanelOperations.validate(); topPanelOperations.repaint(); topPanelNotifications.invalidate(); topPanelNotifications.removeAll(); topPanelNotifications.validate(); topPanelNotifications.repaint(); topPanelMetadata.invalidate(); topPanelMetadata.removeAll(); topPanelMetadata.validate(); topPanelMetadata.repaint(); mbeansTab.getButtonAt(0).setEnabled(false); mbeansTab.getButtonAt(1).setEnabled(false); mbeansTab.getButtonAt(2).setEnabled(false); mbeansTab.getButtonAt(3).setEnabled(false); validate(); repaint(); } /** * Subscribe button action. */ private void registerListener() { SwingWorker sw = new SwingWorker() { @Override public Void doInBackground() throws InstanceNotFoundException, IOException { mbeanNotifications.registerListener(currentNode); return null; } @Override protected void done() { try { get(); updateNotifications(); validate(); } catch (Exception e) { Throwable t = Utils.getActualException(e); LOGGER.log(Level.SEVERE, "Problem adding listener", t); // NOI18N showErrorDialog(t.getMessage(), Resources.getText("LBL_ProblemAddingListener")); // NOI18N } } }; mbeansTab.getRequestProcessor().post(sw); } /** * Unsubscribe button action. */ private void unregisterListener() { SwingWorker sw = new SwingWorker() { @Override public Boolean doInBackground() { return mbeanNotifications.unregisterListener(currentNode); } @Override protected void done() { try { if (get()) { updateNotifications(); validate(); } } catch (Exception e) { Throwable t = Utils.getActualException(e); LOGGER.log(Level.SEVERE, "Problem removing listener", t); // NOI18N showErrorDialog(t.getMessage(), Resources.getText("LBL_ProblemRemovingListener")); // NOI18N } } }; mbeansTab.getRequestProcessor().post(sw); } /** * Refresh button action. */ private void refreshAttributes() { mbeanAttributes.refreshAttributes(); } // Call on EDT private void updateNotifications() { if (mbeanNotifications.isListenerRegistered(mbean)) { long received = mbeanNotifications.getReceivedNotifications(mbean); updateReceivedNotifications(currentNode, received); } else { clearNotifications(); } } /** * Update notification node label in MBean tree: "Notifications[received]". */ // Call on EDT private void updateReceivedNotifications( DefaultMutableTreeNode emitter, long received) { String text = Resources.getText("LBL_Notifications") + "[" + received + "]"; // NOI18N updateNotificationsNodeLabel(emitter, text); } /** * Update notification node label in MBean tree: "Notifications". */ // Call on EDT private void clearNotifications() { updateNotificationsNodeLabel(currentNode, Resources.getText("LBL_Notifications")); // NOI18N } /** * Update notification node label in MBean tree: "Notifications[0]". */ // Call on EDT private void clearNotifications0() { updateNotificationsNodeLabel(currentNode, Resources.getText("LBL_Notifications") + "[0]"); // NOI18N } /** * Update the label of the supplied MBean tree node. */ // Call on EDT private void updateNotificationsNodeLabel( DefaultMutableTreeNode node, String label) { // Find Notifications TabButton and update text DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent(); if (node != selectedNode) { return; } invalidate(); mbeansTab.getButtonAt(2).setText(label); validate(); repaint(); } /** * Clear button action. */ // Call on EDT private void clearCurrentNotifications() { mbeanNotifications.clearCurrentNotifications(); if (mbeanNotifications.isListenerRegistered(mbean)) { // Update notifs in MBean tree "Notifications[0]". // // Notification buffer has been cleared with a listener been // registered so add "[0]" at the end of the node label. // clearNotifications0(); } else { // Update notifs in MBean tree "Notifications". // // Notification buffer has been cleared without a listener been // registered so don't add "[0]" at the end of the node label. // clearNotifications(); } } // Call on EDT private void clear() { mbeanAttributes.stopCellEditing(); mbeanAttributes.emptyTable(); mbeanAttributes.removeAttributes(); mbeanOperations.removeOperations(); mbeanNotifications.stopCellEditing(); mbeanNotifications.emptyTable(); mbeanNotifications.disableNotifications(); mbeanInfo.emptyInfoTable(); mbean = null; currentNode = null; } /** * Notification listener: handles asynchronous reception * of MBean operation results and MBean notifications. */ // Call on EDT public void handleNotification(Notification e, Object handback) { // Operation result if (e.getType().equals(XMBeanOperations.OPERATION_INVOCATION_EVENT)) { final Object message; if (handback == null) { JTextArea textArea = new JTextArea("null"); // NOI18N textArea.setEditable(false); textArea.setEnabled(true); textArea.setRows(textArea.getLineCount()); message = textArea; } else { Component comp = mbeansTab.getDataViewer(). createOperationViewer(handback, mbean); if (comp == null) { JTextArea textArea = new JTextArea(handback.toString()); textArea.setEditable(false); textArea.setEnabled(true); textArea.setRows(textArea.getLineCount()); JScrollPane scrollPane = new JScrollPane(textArea); Dimension d = scrollPane.getPreferredSize(); if (d.getWidth() > 400 || d.getHeight() > 250) { scrollPane.setPreferredSize(new Dimension(400, 250)); } message = scrollPane; } else { if (!(comp instanceof JScrollPane)) { comp = new JScrollPane(comp); } Dimension d = comp.getPreferredSize(); if (d.getWidth() > 400 || d.getHeight() > 250) { comp.setPreferredSize(new Dimension(400, 250)); } message = comp; } } new ThreadDialog( (Component) e.getSource(), message, Resources.getText("LBL_OperationReturnValue"), // NOI18N JOptionPane.INFORMATION_MESSAGE).run(); } // Got notification else if (e.getType().equals( XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) { DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback; Long received = (Long) e.getUserData(); updateReceivedNotifications(emitter, received.longValue()); } } /** * Action listener: handles actions in panel buttons */ // Call on EDT public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof JButton) { JButton button = (JButton) e.getSource(); // Refresh button if (button == refreshButton) { refreshAttributes(); return; } // Clear button if (button == clearButton) { clearCurrentNotifications(); return; } // Subscribe button if (button == subscribeButton) { registerListener(); return; } // Unsubscribe button if (button == unsubscribeButton) { unregisterListener(); return; } } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XTable.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import javax.swing.*; import javax.swing.table.*; import java.awt.*; import java.io.*; abstract class XTable extends JTable { static final int NAME_COLUMN = 0; static final int VALUE_COLUMN = 1; private Color defaultColor, editableColor, errorColor; private Font normalFont, boldFont; public XTable () { super(); @SuppressWarnings("serial") final TableSorter sorter = new TableSorter(); setModel(sorter); sorter.addMouseListenerToHeaderInTable(this); setRowSelectionAllowed(false); setColumnSelectionAllowed(false); setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); } Color getDefaultColor() { return defaultColor; } Color getEditableColor() { return editableColor; } /** * Called by TableSorter if a mouse event requests to sort the rows. * @param column the column against which the rows are sorted */ void sortRequested(int column) { // This is a hook for subclasses } /** * This returns the select index as the table was at initialization */ public int getSelectedIndex() { return convertRowToIndex(getSelectedRow()); } /* * Converts the row into index (before sorting) */ public int convertRowToIndex(int row) { if (row == -1) return row; if (getModel() instanceof TableSorter) { return ((TableSorter) getModel()).getIndexOfRow(row); } else { return row; } } public void emptyTable() { DefaultTableModel model = (DefaultTableModel)getModel(); while (model.getRowCount()>0) model.removeRow(0); } public abstract boolean isTableEditable(); public abstract boolean isColumnEditable(int column); public abstract boolean isReadable(int row); public abstract boolean isWritable(int row); public abstract boolean isCellError(int row, int col); public abstract boolean isAttributeViewable(int row, int col); public abstract void setTableValue(Object value,int row); public abstract Object getValue(int row); public abstract String getClassName(int row); public abstract String getValueName(int row); public boolean isReadWrite(int row) { return (isReadable(row) && isWritable(row)); } //JTable re-implementation //attribute can be editable even if unavailable @Override public boolean isCellEditable(int row, int col) { return ((isTableEditable() && isColumnEditable(col) && isWritable(row) && Utils.isEditableType(getClassName(row)))); } //attribute can be droppable even if unavailable public boolean isCellDroppable(int row, int col) { return (isTableEditable() && isColumnEditable(col) && isWritable(row)); } //returns null, means no tool tip public String getToolTip(int row, int column) { return null; } /** * This method sets read write rows to be blue, and other rows to be their * default rendered colour. */ @Override public TableCellRenderer getCellRenderer(int row, int column) { DefaultTableCellRenderer tcr = (DefaultTableCellRenderer) super.getCellRenderer(row,column); tcr.setToolTipText(getToolTip(row,column)); if (defaultColor == null) { defaultColor = tcr.getForeground(); editableColor = Color.blue; errorColor = Color.red; // this sometimes happens for some reason if (defaultColor == null) { return tcr; } } if (column != VALUE_COLUMN) { tcr.setForeground(defaultColor); return tcr; } if (isCellError(row,column)) { tcr.setForeground(errorColor); } else if (isCellEditable(row, column)) { tcr.setForeground(editableColor); } else { tcr.setForeground(defaultColor); } return tcr; } @Override public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { Component comp = super.prepareRenderer(renderer, row, column); if (normalFont == null) { normalFont = comp.getFont(); boldFont = normalFont.deriveFont(Font.BOLD); } if (column == VALUE_COLUMN && isAttributeViewable(row, VALUE_COLUMN)) { comp.setFont(boldFont); } else { comp.setFont(normalFont); } return comp; } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XTextField.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.*; import java.awt.dnd.*; import java.awt.event.*; import java.awt.datatransfer.*; import java.io.*; import java.util.*; import javax.swing.plaf.*; import javax.swing.event.*; import javax.swing.*; /** * This list implements the drag and drop functionality. */ @SuppressWarnings("serial") class XTextField extends JPanel implements DocumentListener, ActionListener { private XObject selectedObject; private Class expectedClass; private Object value; protected JTextField textField; private static boolean allowNullSelection = false; protected final static int COMPATIBLE_VALUE = 1; protected final static int CURRENT_VALUE = 2; protected final static int NULL_VALUE = 3; private JButton button; private XMBeanOperations operation; //used in XTestFieldEditor public XTextField() { super(new BorderLayout()); add(textField = new JTextField(),BorderLayout.CENTER); textField.addActionListener(this); // } public XTextField(Object value) { this(value,value.toString().length()); } public XTextField(Object value, int colWidth) { this(value,value.getClass(),colWidth, true, null, null); } public XTextField(Object value, Class expectedClass, int colWidth, boolean isCallable, JButton button, XMBeanOperations operation) { super(new BorderLayout()); this.expectedClass = expectedClass; this.button = button; this.operation = operation; add(textField = new JTextField(value.toString(),colWidth), BorderLayout.CENTER); if(isCallable) textField.addActionListener(this); boolean fieldEditable = expectedClass == null ? false : Utils.isEditableType(expectedClass.getName()); if (fieldEditable && isCallable) { textField.setEditable(true); } else { textField.setEditable(false); } } public static void setNullSelectionAllowed(boolean allowNullSelection) { XTextField.allowNullSelection = allowNullSelection; } public static boolean getNullSelectionAllowed() { return allowNullSelection; } protected void init(Object value, Class expectedClass) { this.expectedClass = expectedClass; this.value = value; boolean fieldEditable = expectedClass == null ? false : Utils.isEditableType(expectedClass.getName()); clearObject(); if (value != null) { textField.setText(value.toString()); } else { //null String value for the moment textField.setText(""); // NOI18N } textField.setToolTipText(null); if (fieldEditable) { if (!textField.isEditable()) { textField.setEditable(true); } } else { if (textField.isEditable()) { textField.setEditable(false); } } } private synchronized void setObject(XObject object) { clearObject(); selectedObject = object; setSelectedColors(); textField.setText(object.getText()); textField.getDocument().addDocumentListener(this); paintImmediately(getVisibleRect()); } private synchronized void clearObject() { textField.getDocument().removeDocumentListener(this); selectedObject = null; setDefaultColors(); } private synchronized void setSelectedColors() { // fore = textField.getForeground(); // back = textField.getBackground(); //textField.setForeground(Color.red); // textField.setBackground(Color.yellow); } private synchronized void setDefaultColors() { // if (fore != null) textField.setForeground(fore); // if (back != null) textField.setBackground(back); } public void setHorizontalAlignment(int h) { textField.setHorizontalAlignment(h); } //can be overwritten protected JMenuItem buildJMenuItem(XObject xobject, int valueType) { if (valueType == COMPATIBLE_VALUE) { return new JMenuItem(xobject.getText()); } else if (valueType == CURRENT_VALUE) { return new JMenuItem("> "+xobject.getText()); // NOI18N } else if (valueType == NULL_VALUE) { return new JMenuItem("null"); // NOI18N } else { return null; } } private JPopupMenu buildEditPopupMenu() { JPopupMenu menu = new JPopupMenu(); return menu; } // ACTIONLISTENER IMPLEMENTATION public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof JTextField) { if(operation != null) operation.performInvokeRequest(button); } } /** * This method returns either the user inputted String, or an XObject * if one was dropped on the input field. */ public Object getValue() { if (selectedObject!=null) { if (selectedObject == XObject.NULL_OBJECT) { //null case return null; } else { return selectedObject; } } else { return textField.getText(); } } public void changedUpdate(DocumentEvent e) { // the user typed something, so remove references // to the obejct that was dropped. clearObject(); } public void removeUpdate(DocumentEvent e) { // the user typed something, so remove references // to the obejct that was dropped. clearObject(); } public void insertUpdate(DocumentEvent e) { // the user typed something, so remove references // to the obejct that was dropped. clearObject(); } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XTextFieldEditor.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.Component; import java.util.EventObject; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; @SuppressWarnings("serial") class XTextFieldEditor extends XTextField implements TableCellEditor { protected EventListenerList evtListenerList = new EventListenerList(); protected ChangeEvent changeEvent = new ChangeEvent(this); private FocusListener editorFocusListener = new FocusAdapter() { @Override public void focusLost(FocusEvent e) { // https://java.net/jira/browse/VISUALVM-167 // must not call fireEditingStopped() here! } }; public XTextFieldEditor() { super(); textField.addFocusListener(editorFocusListener); } //edition stopped ou JMenuItem selection & JTextField selection @Override public void actionPerformed(ActionEvent e) { super.actionPerformed(e); if ((e.getSource() instanceof JMenuItem) || (e.getSource() instanceof JTextField)) { fireEditingStopped(); } } //edition stopped on drag & drop success protected void dropSuccess() { fireEditingStopped(); } //TableCellEditor implementation public void addCellEditorListener(CellEditorListener listener) { evtListenerList.add(CellEditorListener.class,listener); } public void removeCellEditorListener(CellEditorListener listener) { evtListenerList.remove(CellEditorListener.class, listener); } protected void fireEditingStopped() { CellEditorListener listener; Object[] listeners = evtListenerList.getListenerList(); for (int i=0;i< listeners.length;i++) { if (listeners[i] == CellEditorListener.class) { listener = (CellEditorListener) listeners[i+1]; listener.editingStopped(changeEvent); } } } protected void fireEditingCanceled() { CellEditorListener listener; Object[] listeners = evtListenerList.getListenerList(); for (int i=0;i< listeners.length;i++) { if (listeners[i] == CellEditorListener.class) { listener = (CellEditorListener) listeners[i+1]; listener.editingCanceled(changeEvent); } } } public void cancelCellEditing() { fireEditingCanceled(); } public boolean stopCellEditing() { fireEditingStopped(); return true; } public boolean isCellEditable(EventObject event) { return true; } public boolean shouldSelectCell(EventObject event) { return true; } public Object getCellEditorValue() { Object object = getValue(); if (object instanceof XObject) { return ((XObject) object).getObject(); } else { return object; } } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { String className; if (table instanceof XTable) { XTable mytable = (XTable) table; className = mytable.getClassName(row); } else { className = String.class.getName(); } Class clazz; try { clazz = Utils.getClass(className); } catch (ClassNotFoundException e) { clazz = null; } init(value, clazz); return this; } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XTree.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.util.*; import javax.management.*; import javax.swing.*; import javax.swing.tree.*; import org.graalvm.visualvm.modules.mbeans.options.GlobalPreferences; import static org.graalvm.visualvm.modules.mbeans.XNodeInfo.Type; @SuppressWarnings("serial") class XTree extends JTree { private List orderedKeyPropertyList; private MBeansTab mbeansTab; private Map nodes = new HashMap(); public XTree(MBeansTab mbeansTab) { super(new DefaultMutableTreeNode("MBeanTreeRootNode")); // NOI18N this.mbeansTab = mbeansTab; setRootVisible(false); setShowsRootHandles(true); ToolTipManager.sharedInstance().registerComponent(this); orderedKeyPropertyList = getOrderedKeyPropertyList(); } /** * This method removes the node from its parent */ // Call on EDT private synchronized void removeChildNode(DefaultMutableTreeNode child) { DefaultTreeModel model = (DefaultTreeModel) getModel(); model.removeNodeFromParent(child); } /** * This method adds the child to the specified parent node * at specific index. */ // Call on EDT private synchronized void addChildNode( DefaultMutableTreeNode parent, DefaultMutableTreeNode child, int index) { DefaultTreeModel model = (DefaultTreeModel) getModel(); boolean isRootLeaf = (parent == model.getRoot()) && parent.isLeaf(); model.insertNodeInto(child, parent, index); // Make the root node's children visible if the // parent node is the root node and is a leaf if (isRootLeaf) { model.nodeStructureChanged(parent); } } /** * This method adds the child to the specified parent node. * The index where the child is to be added depends on the * child node being Comparable or not. If the child node is * not Comparable then it is added at the end, i.e. right * after the current parent's children. */ // Call on EDT private synchronized void addChildNode( DefaultMutableTreeNode parent, DefaultMutableTreeNode child) { int childCount = parent.getChildCount(); if (childCount == 0) { addChildNode(parent, child, 0); return; } if (child instanceof ComparableDefaultMutableTreeNode) { ComparableDefaultMutableTreeNode comparableChild = (ComparableDefaultMutableTreeNode) child; for (int i = childCount - 1; i >= 0; i--) { DefaultMutableTreeNode brother = (DefaultMutableTreeNode) parent.getChildAt(i); // "child >= brother", add child after brother if (comparableChild.compareTo(brother) >= 0) { addChildNode(parent, child, i + 1); return; } } // "child < all brothers", add at the beginning addChildNode(parent, child, 0); return; } // "child not comparable", add at the end addChildNode(parent, child, childCount); } /** * This method removes all the displayed nodes from the tree, * but does not affect actual MBeanServer contents. */ // Call on EDT @Override public synchronized void removeAll() { DefaultTreeModel model = (DefaultTreeModel) getModel(); DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); root.removeAllChildren(); model.nodeStructureChanged(root); nodes.clear(); } // Call on EDT public synchronized void removeMBeanFromView(ObjectName mbean) { // We assume here that MBeans are removed one by one (on MBean // unregistered notification). Deletes the tree node associated // with the given MBean and recursively all the node parents // which are leaves and non XMBean. // DefaultMutableTreeNode node = null; Dn dn = new Dn(mbean, orderedKeyPropertyList); if (dn.getTokenCount() > 0) { DefaultTreeModel model = (DefaultTreeModel) getModel(); Token token = dn.getToken(0); String hashKey = dn.getHashKey(token); node = nodes.get(hashKey); if ((node != null) && (!node.isRoot())) { if (node.getChildCount() > 0) { String label = token.getValue(); XNodeInfo userObject = new XNodeInfo( Type.NONMBEAN, label, label, token.getTokenValue()); changeNodeValue(node, userObject); } else { DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent(); model.removeNodeFromParent(node); nodes.remove(hashKey); removeParentFromView(dn, 1, parent); } } } } /** * Removes only the parent nodes which are non MBean and leaf. * This method assumes the child nodes have been removed before. */ // Call on EDT private DefaultMutableTreeNode removeParentFromView( Dn dn, int index, DefaultMutableTreeNode node) { if ((!node.isRoot()) && node.isLeaf() && (!(((XNodeInfo) node.getUserObject()).getType().equals(Type.MBEAN)))) { DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent(); removeChildNode(node); String hashKey = dn.getHashKey(dn.getToken(index)); nodes.remove(hashKey); removeParentFromView(dn, index + 1, parent); } return node; } // Call on EDT public synchronized void addMBeansToView(Set mbeans) { Set dns = new TreeSet(); for (ObjectName mbean : mbeans) { Dn dn = new Dn(mbean, orderedKeyPropertyList); dns.add(dn); } for (Dn dn : dns) { ObjectName mbean = dn.getObjectName(); XMBean xmbean = new XMBean(mbean, mbeansTab); addMBeanToView(mbean, xmbean, dn); } } // Call on EDT public synchronized void addMBeanToView(ObjectName mbean) { // Build XMBean for the given MBean // XMBean xmbean = new XMBean(mbean, mbeansTab); // Build Dn for the given MBean // Dn dn = new Dn(mbean, orderedKeyPropertyList); // Add the new nodes to the MBean tree from leaf to root // addMBeanToView(mbean, xmbean, dn); } // Call on EDT private synchronized void addMBeanToView( ObjectName mbean, XMBean xmbean, Dn dn) { DefaultMutableTreeNode childNode = null; DefaultMutableTreeNode parentNode = null; // Add the node or replace its user object if already added // Token token = dn.getToken(0); String hashKey = dn.getHashKey(token); if (nodes.containsKey(hashKey)) { // Found existing node previously created when adding another node // childNode = nodes.get(hashKey); // Replace user object to reflect that this node is an MBean // Object data = createNodeValue(xmbean, token); String label = data.toString(); XNodeInfo userObject = new XNodeInfo(Type.MBEAN, data, label, mbean.toString()); changeNodeValue(childNode, userObject); return; } // Create new leaf node // childNode = createDnNode(dn, token, xmbean); nodes.put(hashKey, childNode); // Add intermediate non MBean nodes // for (int i = 1; i < dn.getTokenCount(); i++) { token = dn.getToken(i); hashKey = dn.getHashKey(token); if (nodes.containsKey(hashKey)) { // Intermediate node already present, add new node as child // parentNode = nodes.get(hashKey); addChildNode(parentNode, childNode); return; } else { // Create new intermediate node // if ("domain".equals(token.getTokenType())) { // NOI18N parentNode = createDomainNode(dn, token); DefaultMutableTreeNode root = (DefaultMutableTreeNode) getModel().getRoot(); addChildNode(root, parentNode); } else { parentNode = createSubDnNode(dn, token); } nodes.put(hashKey, parentNode); addChildNode(parentNode, childNode); } childNode = parentNode; } } // Call on EDT private synchronized void changeNodeValue( DefaultMutableTreeNode node, XNodeInfo nodeValue) { if (node instanceof ComparableDefaultMutableTreeNode) { // should it stay at the same place? DefaultMutableTreeNode clone = (DefaultMutableTreeNode) node.clone(); clone.setUserObject(nodeValue); if (((ComparableDefaultMutableTreeNode) node).compareTo(clone) == 0) { // the order in the tree didn't change node.setUserObject(nodeValue); DefaultTreeModel model = (DefaultTreeModel) getModel(); model.nodeChanged(node); } else { // delete the node and re-order it in case the // node value modifies the order in the tree DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent(); removeChildNode(node); node.setUserObject(nodeValue); addChildNode(parent, node); } } else { // not comparable stays at the same place node.setUserObject(nodeValue); DefaultTreeModel model = (DefaultTreeModel) getModel(); model.nodeChanged(node); } // Clear the current selection and set it // again so valueChanged() gets called if (node == getLastSelectedPathComponent()) { TreePath selectionPath = getSelectionPath(); clearSelection(); setSelectionPath(selectionPath); } } /** * Creates the domain node. */ private DefaultMutableTreeNode createDomainNode(Dn dn, Token token) { DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode(); String label = dn.getDomain(); XNodeInfo userObject = new XNodeInfo(Type.NONMBEAN, label, label, label); node.setUserObject(userObject); return node; } /** * Creates the node corresponding to the whole Dn, i.e. an MBean. */ private DefaultMutableTreeNode createDnNode( Dn dn, Token token, XMBean xmbean) { DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode(); Object data = createNodeValue(xmbean, token); String label = data.toString(); XNodeInfo userObject = new XNodeInfo(Type.MBEAN, data, label, xmbean.getObjectName().toString()); node.setUserObject(userObject); return node; } /** * Creates the node corresponding to a subDn, i.e. a non-MBean * intermediate node. */ private DefaultMutableTreeNode createSubDnNode(Dn dn, Token token) { DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode(); String label = isKeyValueView() ? token.getTokenValue() : token.getValue(); XNodeInfo userObject = new XNodeInfo(Type.NONMBEAN, label, label, token.getTokenValue()); node.setUserObject(userObject); return node; } private Object createNodeValue(XMBean xmbean, Token token) { String label = isKeyValueView() ? token.getTokenValue() : token.getValue(); xmbean.setText(label); return xmbean; } private List getOrderedKeyPropertyList() { if (orderedKeyPropertyList == null) { orderedKeyPropertyList = new ArrayList(); String keyPropertyList = GlobalPreferences.sharedInstance().getOrderedKeyPropertyList(); if (keyPropertyList.isEmpty()) { orderedKeyPropertyList.add("type"); // NOI18N orderedKeyPropertyList.add("j2eeType"); // NOI18N } else { String[] tokens = keyPropertyList.split(","); // NOI18N for (String token : tokens) { orderedKeyPropertyList.add(token); } } } return orderedKeyPropertyList; } /** * Parses the MBean ObjectName comma-separated properties string and puts * the individual key/value pairs into the map. Key order in the properties * string is preserved by the map. */ private static Map extractKeyValuePairs( String props, ObjectName mbean) { Map map = new LinkedHashMap(); int eq = props.indexOf("="); // NOI18N while (eq != -1) { String key = props.substring(0, eq); String value = mbean.getKeyProperty(key); map.put(key, value); props = props.substring(key.length() + 1 + value.length()); if (props.startsWith(",")) { // NOI18N props = props.substring(1); } eq = props.indexOf("="); // NOI18N } return map; } /** * Returns the ordered key property list that will be used to build the * MBean tree. If the "com.sun.tools.jconsole.mbeans.keyPropertyList" system * property is not specified, then the ordered key property list used * to build the MBean tree will be the one returned by the method * ObjectName.getKeyPropertyListString() with "type" as first key, * and "j2eeType" as second key, if present. If any of the keys specified * in the comma-separated key property list does not apply to the given * MBean then it will be discarded. */ private static String getKeyPropertyListString( ObjectName mbean, List orderedKeyPropertyList) { String props = mbean.getKeyPropertyListString(); Map map = extractKeyValuePairs(props, mbean); StringBuilder sb = new StringBuilder(); // Add the key/value pairs to the buffer following the // key order defined by the "orderedKeyPropertyList" for (String key : orderedKeyPropertyList) { if (map.containsKey(key)) { sb.append(key + "=" + map.get(key) + ","); // NOI18N map.remove(key); } } // Add the remaining key/value pairs to the buffer for (Map.Entry entry : map.entrySet()) { sb.append(entry.getKey() + "=" + entry.getValue() + ","); // NOI18N } String orderedKeyPropertyListString = sb.toString(); orderedKeyPropertyListString = orderedKeyPropertyListString.substring( 0, orderedKeyPropertyListString.length() - 1); return orderedKeyPropertyListString; } // // Tree preferences // private static boolean treeView; private static boolean treeViewInit = false; private static boolean isTreeView() { if (!treeViewInit) { treeView = getTreeViewValue(); treeViewInit = true; } return treeView; } private static boolean getTreeViewValue() { String tv = System.getProperty("treeView"); // NOI18N return ((tv == null) ? true : !(tv.equals("false"))); // NOI18N } // // MBean key-value preferences // private boolean keyValueView = Boolean.getBoolean("keyValueView"); // NOI18N private boolean isKeyValueView() { return keyValueView; } // // Utility classes // private static class ComparableDefaultMutableTreeNode extends DefaultMutableTreeNode implements Comparable { public int compareTo(DefaultMutableTreeNode node) { return (this.toString().compareTo(node.toString())); } } private static class Dn implements Comparable { private ObjectName mbean; private String domain; private String keyPropertyList; private String hashDn; private List tokens = new ArrayList(); public Dn(ObjectName mbean, List orderedKeyPropertyList) { this.mbean = mbean; this.domain = mbean.getDomain(); this.keyPropertyList = getKeyPropertyListString(mbean, orderedKeyPropertyList); if (isTreeView()) { // Tree view Map map = extractKeyValuePairs(keyPropertyList, mbean); for (Map.Entry entry : map.entrySet()) { tokens.add(new Token("key", entry.getKey() + "=" + entry.getValue())); // NOI18N } } else { // Flat view tokens.add(new Token("key", "properties=" + keyPropertyList)); // NOI18N } // Add the domain as the first token in the Dn tokens.add(0, new Token("domain", "domain=" + domain)); // NOI18N // Reverse the Dn (from leaf to root) Collections.reverse(tokens); // Compute hash for Dn computeHashDn(); } public ObjectName getObjectName() { return mbean; } public String getDomain() { return domain; } public String getKeyPropertyList() { return keyPropertyList; } public Token getToken(int index) { return tokens.get(index); } public int getTokenCount() { return tokens.size(); } public String getHashDn() { return hashDn; } public String getHashKey(Token token) { final int begin = hashDn.indexOf(token.getTokenValue()); return hashDn.substring(begin, hashDn.length()); } private void computeHashDn() { if (tokens.isEmpty()) { return; } final StringBuilder hdn = new StringBuilder(); for (int i = 0; i < tokens.size(); i++) { hdn.append(tokens.get(i).getTokenValue()); hdn.append(","); // NOI18N } hashDn = hdn.substring(0, hdn.length() - 1); } @Override public String toString() { return domain + ":" + keyPropertyList; // NOI18N } public int compareTo(Dn dn) { return this.toString().compareTo(dn.toString()); } } private static class Token { private String tokenType; private String tokenValue; private String key; private String value; public Token(String tokenType, String tokenValue) { this.tokenType = tokenType; this.tokenValue = tokenValue; buildKeyValue(); } public String getTokenType() { return tokenType; } public String getTokenValue() { return tokenValue; } public String getKey() { return key; } public String getValue() { return value; } private void buildKeyValue() { int index = tokenValue.indexOf("="); // NOI18N if (index < 0) { key = tokenValue; value = tokenValue; } else { key = tokenValue.substring(0, index); value = tokenValue.substring(index + 1, tokenValue.length()); } } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XTreeRenderer.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans; import java.awt.Component; import javax.swing.ImageIcon; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; class XTreeRenderer extends DefaultTreeCellRenderer { @Override public Component getTreeCellRendererComponent( JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent( tree, value, selected, expanded, leaf, row, hasFocus); Object userObject = ((DefaultMutableTreeNode) value).getUserObject(); if (userObject instanceof XNodeInfo) { XNodeInfo node = (XNodeInfo) userObject; setToolTipText(node.getToolTipText()); switch (node.getType()) { case MBEAN: XMBean xmbean = (XMBean) node.getData(); setIcon((ImageIcon) xmbean.getIcon()); break; case NONMBEAN: break; case ATTRIBUTES: case OPERATIONS: case NOTIFICATIONS: setIcon(null); break; case ATTRIBUTE: case OPERATION: case NOTIFICATION: setIcon(null); break; } } else { setToolTipText(null); } return this; } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/options/Bundle.properties ================================================ # # Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OptionsCategory_Name_MBeans=MBeans LBL_MBeansBrowser=MBeans Browser LBL_Plotters=&Plotters polling period\: LBL_Sec=sec. LBL_Ordered_Key_Property_List=&Ordered key property list\: MSG_CommaSeparatedListOfKeys=Comma-separated list of keys ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/options/GlobalPreferences.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans.options; import org.graalvm.visualvm.core.datasupport.ComparableWeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; import java.util.prefs.BackingStoreException; import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; import java.util.prefs.Preferences; import org.openide.util.NbPreferences; /** * * @author Luis-Miguel Alventosa */ public class GlobalPreferences implements PreferenceChangeListener { private final static Logger LOGGER = Logger.getLogger("org.graalvm.visualvm.modules.mbeans.options"); // NOI18N private static final String INT_KEY_PLOTTERS_POLL = "PlottersPoll"; // NOI18N private static final int PLOTTERS_POLL_DEFAULT = 4; private static final String STRING_KEY_ORDERED_KEY_PROPERTY_LIST = "OrderedKeyPropertyList"; // NOI18N private static final String ORDERED_KEY_PROPERTY_LIST_DEFAULT = ""; // NOI18N private final static GlobalPreferences INSTANCE = new GlobalPreferences(); private final Preferences prefs; private final Map>> listenerMap = new HashMap>>(); private final ExecutorService dispatcher = Executors.newCachedThreadPool(); private GlobalPreferences() { prefs = NbPreferences.forModule(GlobalPreferences.class); prefs.addPreferenceChangeListener(this); } public static GlobalPreferences sharedInstance() { return INSTANCE; } public void preferenceChange(final PreferenceChangeEvent evt) { synchronized(listenerMap) { Set> set = listenerMap.get(evt.getKey()); if (set != null) { final Set tmpListeners = new HashSet(); Collection> deadRefs = new ArrayList>(); for(ComparableWeakReference pclRef : set) { if (pclRef.get() != null) { tmpListeners.add(pclRef.get()); } else { deadRefs.add(pclRef); } } set.removeAll(deadRefs); dispatcher.submit(new Runnable() { public void run() { for(PreferenceChangeListener pcl : tmpListeners) { pcl.preferenceChange(evt); } } }); } } } public int getPlottersPoll() { return getPollingInterval(INT_KEY_PLOTTERS_POLL, PLOTTERS_POLL_DEFAULT); } public void setPlottersPoll(int value) { setPollingInterval(INT_KEY_PLOTTERS_POLL, value); } public void watchPlottersPoll(PreferenceChangeListener pcl) { addListener(INT_KEY_PLOTTERS_POLL, pcl); } public String getOrderedKeyPropertyList() { synchronized(prefs) { return prefs.get(STRING_KEY_ORDERED_KEY_PROPERTY_LIST, ORDERED_KEY_PROPERTY_LIST_DEFAULT); } } public void setOrderedKeyPropertyList(String value) { synchronized(prefs) { prefs.put(STRING_KEY_ORDERED_KEY_PROPERTY_LIST, value); } } public void watchOrderedKeyPropertyList(PreferenceChangeListener pcl) { addListener(STRING_KEY_ORDERED_KEY_PROPERTY_LIST, pcl); } public boolean store() { try { prefs.sync(); return true; } catch (BackingStoreException ex) { LOGGER.log(Level.SEVERE, "Error saving preferences", ex); // NOI18N } return false; } private void addListener(String property, PreferenceChangeListener pcl) { synchronized(listenerMap) { if (listenerMap.containsKey(property)) { Set> set = listenerMap.get(property); set.add(new ComparableWeakReference(pcl)); } else { Set> set = new HashSet>(); set.add(new ComparableWeakReference(pcl)); listenerMap.put(property, set); } } } private int getPollingInterval(String property, int deflt) { int value = -1; synchronized (prefs) { value = prefs.getInt(property, -1); if (value == -1) { value = deflt; prefs.putInt(property, value); } } return value; } private void setPollingInterval(String property, int value) { synchronized(prefs) { prefs.putInt(property, value); } } } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/options/MBeansOptionsPanel.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans.options; import org.graalvm.visualvm.core.options.UISupport; import org.graalvm.visualvm.core.ui.components.SectionSeparator; import org.graalvm.visualvm.core.ui.components.Spacer; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.SpinnerNumberModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.openide.awt.Mnemonics; import org.openide.util.NbBundle; /** * * @author Jiri Sedlacek */ public class MBeansOptionsPanel extends JPanel { private final MBeansOptionsPanelController controller; private final ChangeListener changeListener = new ChangeListener() { public void stateChanged(ChangeEvent e) { controller.changed(); } }; MBeansOptionsPanel(MBeansOptionsPanelController controller) { this.controller = controller; initComponents(); startTrackingChanges(); } void load() { // TODO read settings and initialize GUI // Example: // someCheckBox.setSelected(Preferences.userNodeForPackage(CorePanel.class).getBoolean("someFlag", false)); // or for org.openide.util with API spec. version >= 7.4: // someCheckBox.setSelected(NbPreferences.forModule(CorePanel.class).getBoolean("someFlag", false)); // or: // someTextField.setText(SomeSystemOption.getDefault().getSomeStringProperty()); plottersSpinner.setValue(GlobalPreferences.sharedInstance().getPlottersPoll()); propertyListField.setText(GlobalPreferences.sharedInstance().getOrderedKeyPropertyList()); } void store() { GlobalPreferences.sharedInstance().setPlottersPoll((Integer) plottersSpinner.getValue()); GlobalPreferences.sharedInstance().setOrderedKeyPropertyList(propertyListField.getText()); // TODO store modified settings // Example: // Preferences.userNodeForPackage(CorePanel.class).putBoolean("someFlag", someCheckBox.isSelected()); // or for org.openide.util with API spec. version >= 7.4: // NbPreferences.forModule(CorePanel.class).putBoolean("someFlag", someCheckBox.isSelected()); // or: // SomeSystemOption.getDefault().setSomeStringProperty(someTextField.getText()); GlobalPreferences.sharedInstance().store(); } boolean valid() { try { return (Integer)plottersSpinner.getValue() > 0; } catch (Exception e) {} return false; } private void initComponents() { GridBagConstraints c; setLayout(new GridBagLayout()); // pollingSeparator SectionSeparator pollingSeparator = UISupport.createSectionSeparator( NbBundle.getMessage(MBeansOptionsPanel.class, "LBL_MBeansBrowser")); // NOI18N c = new GridBagConstraints(); c.gridy = 0; c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(0, 0, 5, 0); add(pollingSeparator, c); // plottersLabel JLabel plottersLabel = new JLabel(); Mnemonics.setLocalizedText(plottersLabel, NbBundle.getMessage( MBeansOptionsPanel.class, "LBL_Plotters")); // NOI18N c = new GridBagConstraints(); c.gridx = 0; c.gridy = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(3, 15, 3, 0); add(plottersLabel, c); // plottersSpinner plottersSpinner = new JSpinner(); plottersLabel.setLabelFor(plottersSpinner); plottersSpinner.setModel(new SpinnerNumberModel(3, 1, 99999, 1)); c = new GridBagConstraints(); c.gridx = 1; c.gridy = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(3, 5, 3, 4); add(plottersSpinner, c); // plottersUnits JLabel plottersUnits = new JLabel(); Mnemonics.setLocalizedText(plottersUnits, NbBundle.getMessage( MBeansOptionsPanel.class, "LBL_Sec")); // NOI18N c = new GridBagConstraints(); c.gridx = 2; c.gridy = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(3, 0, 3, 0); add(plottersUnits, c); // propertyListLabel JLabel propertyListLabel = new JLabel(); Mnemonics.setLocalizedText(propertyListLabel, NbBundle.getMessage( MBeansOptionsPanel.class, "LBL_Ordered_Key_Property_List")); // NOI18N c = new GridBagConstraints(); c.gridx = 0; c.gridy = 2; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(3, 15, 3, 0); add(propertyListLabel, c); // propertyListField propertyListField = new JTextField(); propertyListLabel.setLabelFor(propertyListField); propertyListField.setToolTipText(NbBundle.getMessage( MBeansOptionsPanel.class, "MSG_CommaSeparatedListOfKeys")); // NOI18N c = new GridBagConstraints(); c.gridx = 1; c.gridy = 2; c.anchor = GridBagConstraints.WEST; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(3, 5, 3, 0); add(propertyListField, c); // filler c = new GridBagConstraints(); c.gridx = 0; c.gridy = 3; c.weightx = 1; c.weighty = 1; c.anchor = GridBagConstraints.NORTHWEST; c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; add(Spacer.create(), c); } private void startTrackingChanges() { plottersSpinner.getModel().addChangeListener(changeListener); } private JSpinner plottersSpinner; private JTextField propertyListField; } ================================================ FILE: plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/options/MBeansOptionsPanelController.java ================================================ /* * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.mbeans.options; import org.graalvm.visualvm.core.options.UISupport; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import javax.swing.JComponent; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.HelpCtx; import org.openide.util.Lookup; /** * * @author Luis-Miguel Alventosa */ @OptionsPanelController.TopLevelRegistration( id = "MBeansOptions", categoryName = "#OptionsCategory_Name_MBeans", iconBase = "org/graalvm/visualvm/modules/mbeans/ui/resources/mbeans32.png", position = 4000 ) public final class MBeansOptionsPanelController extends OptionsPanelController { private MBeansOptionsPanel panel; private JComponent component; private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private boolean changed; public void update() { getPanel().load(); changed = false; } public void applyChanges() { getPanel().store(); changed = false; } public void cancel() { // need not do anything special, if no changes have been persisted yet } public boolean isValid() { return getPanel().valid(); } public boolean isChanged() { return changed; } public HelpCtx getHelpCtx() { return null; // new HelpCtx("...ID") if you have a help set } public JComponent getComponent(Lookup masterLookup) { return getComponent(); } public void addPropertyChangeListener(PropertyChangeListener l) { pcs.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { pcs.removePropertyChangeListener(l); } private MBeansOptionsPanel getPanel() { if (panel == null) { panel = new MBeansOptionsPanel(this); } return panel; } private JComponent getComponent() { if (component == null) { component = UISupport.createScrollableContainer(getPanel()); } return component; } void changed() { if (!changed) { changed = true; pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true); } pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null); } } ================================================ FILE: plugins/nbproject/build-impl.xml ================================================ ================================================ FILE: plugins/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=b0c79715 build.xml.script.CRC32=1bdb7168 build.xml.stylesheet.CRC32=531c622b # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=b0c79715 nbproject/build-impl.xml.script.CRC32=01096de6 nbproject/build-impl.xml.stylesheet.CRC32=0f381476@2.73 nbproject/platform.xml.data.CRC32=b0c79715 nbproject/platform.xml.script.CRC32=6dcbd131 nbproject/platform.xml.stylesheet.CRC32=45ddf0e0@2.73 ================================================ FILE: plugins/nbproject/platform.properties ================================================ # Deprecated since 5.0u1; for compatibility with 5.0: disabled.clusters= enabled.clusters=\ platform,\ profiler,\ visualvm nbjdk.active=default nbplatform.active=VisualVM_100609-dd12ae64a19c suite.dir=${basedir} netbeans.dest.dir=${suite.dir}/visualvm harness.dir=${suite.dir}/../visualvm/netbeans/harness ================================================ FILE: plugins/nbproject/platform.xml ================================================ ================================================ FILE: plugins/nbproject/project.properties ================================================ modules=\ ${project.net.java.visualvm.modules.glassfish}:\ ${project.org.graalvm.visualvm.modules.jconsole}:\ ${project.org.graalvm.visualvm.modules.mbeans}:\ ${project.com.sun.appserv.management}:\ ${project.org.graalvm.visualvm.modules.extensions}:\ ${project.org.graalvm.visualvm.modules.buffermonitor}:\ ${project.org.graalvm.visualvm.modules.systray}:\ ${project.jsyntaxpane.lib}:\ ${project.org.graalvm.visualvm.modules.oqlsyntax}:\ ${project.org.graalvm.visualvm.modules.tracer}:\ ${project.org.graalvm.visualvm.modules.tracer.monitor}:\ ${project.org.graalvm.visualvm.modules.saplugin}:\ ${project.org.graalvm.visualvm.modules.security}:\ ${project.org.graalvm.visualvm.modules.tracer.io}:\ ${project.org.graalvm.visualvm.modules.tracer.jvmstat}:\ ${project.org.graalvm.visualvm.modules.tracer.dynamic}:\ ${project.org.graalvm.visualvm.modules.tracer.jvm}:\ ${project.org.graalvm.visualvm.modules.threadinspect}:\ ${project.org.graalvm.visualvm.modules.tracer.dtrace}:\ ${project.org.graalvm.visualvm.modules.tracer.javafx}:\ ${project.org.graalvm.visualvm.modules.tracer.swing}:\ ${project.org.graalvm.visualvm.modules.tracer.collections}:\ ${project.org.graalvm.visualvm.profiler.startup}:\ ${project.org.graalvm.visualvm.modules.jolokia}:\ ${project.org.graalvm.visualvm.modules.graaljs} # ${project.org.graalvm.visualvm.jfr.streaming}:\ project.com.sun.appserv.management=glassfish/amx-api project.org.graalvm.visualvm.application.type.custom=extapptypes project.org.graalvm.visualvm.modules.customtype.lib=extapptypes.lib project.org.graalvm.visualvm.modules.graaljs=graaljs project.org.graalvm.visualvm.modules.jolokia=jolokia project.org.graalvm.visualvm.modules.jconsole=jconsole project.org.graalvm.visualvm.modules.mbeans=mbeans project.org.graalvm.visualvm.modules.oqlsyntax=oqlsyntax project.org.graalvm.visualvm.modules.security=security project.org.graalvm.visualvm.modules.systray=systray project.org.graalvm.visualvm.modules.threadinspect=threadinspect project.org.graalvm.visualvm.modules.tracer.collections=tracercollect project.org.graalvm.visualvm.modules.tracer.dtrace=tracerdtrace project.org.graalvm.visualvm.modules.tracer.dynamic=tracerdynamic project.org.graalvm.visualvm.modules.tracer.jvm=tracerjvm project.org.graalvm.visualvm.modules.tracer.swing=tracerswing project.org.graalvm.visualvm.modules.tracer.javafx=tracerjavafx project.net.java.visualvm.modules.glassfish=glassfish project.jsyntaxpane.lib=jsyntaxpane-lib project.org.graalvm.visualvm.modules.extensions=extensions project.org.graalvm.visualvm.modules.saplugin=saplugin project.org.graalvm.visualvm.modules.buffermonitor=buffermonitor project.org.graalvm.visualvm.modules.tracer=tracer project.org.graalvm.visualvm.modules.tracer.io=tracerio project.org.graalvm.visualvm.modules.tracer.jvmstat=tracerjvmstat project.org.graalvm.visualvm.modules.tracer.monitor=tracermonitor project.org.graalvm.visualvm.profiler.startup=startupprofiler project.org.graalvm.visualvm.jfr.streaming=jfr.streaming branding.token=visualvm branding.dir=none run.args.extra=-J-Dsun.java2d.noddraw=true -J-Dsun.java2d.d3d=false ================================================ FILE: plugins/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project.suite plugins ================================================ FILE: plugins/oqlsyntax/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.oqlsyntax. ================================================ FILE: plugins/oqlsyntax/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.modules.oqlsyntax/2 OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/oqlsyntax/Bundle.properties OpenIDE-Module-Requires: org.graalvm.visualvm.editor.SyntaxSupport OpenIDE-Module-Specification-Version: 2.0 ================================================ FILE: plugins/oqlsyntax/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/oqlsyntax/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=ee04bb9c build.xml.script.CRC32=6838e77a build.xml.stylesheet.CRC32=a56c6a5b@2.73 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=ee04bb9c nbproject/build-impl.xml.script.CRC32=da8406b8 nbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73 ================================================ FILE: plugins/oqlsyntax/nbproject/project.properties ================================================ javac.source=1.6 javac.compilerargs=-Xlint -Xlint:-serial license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Jaroslav Bachorik ================================================ FILE: plugins/oqlsyntax/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.oqlsyntax jsyntaxpane.lib 1 0.9.4.1 org.graalvm.visualvm.lib.profiler.oql 2 2.0 org.openide.util.lookup 8.3.1 ================================================ FILE: plugins/oqlsyntax/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/oqlsyntax/resources/README.txt ================================================ 1. Get http://jflex.de/jflex-1.4.3.zip 2. Generate the OqlLexer.java and place it to src/org/graalvm/visualvm/modules/oqlsyntax ================================================ FILE: plugins/oqlsyntax/resources/oql.flex ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 org.graalvm.visualvm.modules.oqlsyntax.lexers; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; %% %public %class OqlLexer %extends DefaultLexer %final %unicode %char %type Token %caseless %{ /** * Default constructor is needed as we will always call the yyreset */ public OqlLexer() { super(); } /** * Helper method to create and return a new Token from of TokenType */ private Token token(TokenType type) { return new Token(type, yychar, yylength()); } %} /* main character classes */ LineTerminator = \r|\n|\r\n InputCharacter = [^\r\n] WhiteSpace = {LineTerminator} | [ \t\f] /* comments */ Comment = {EndOfLineComment} EndOfLineComment = "--" {InputCharacter}* {LineTerminator}? /* identifiers */ Identifier = [:jletter:][:jletterdigit:]* /* integer literals */ DecIntegerLiteral = 0 | [1-9][0-9]* /* floating point literals */ FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] FLit1 = [0-9]+ \. [0-9]* FLit2 = \. [0-9]+ FLit3 = [0-9]+ Exponent = [eE] [+-]? [0-9]+ /* string and character literals */ StringCharacter = [^\r\n\"\\] SingleCharacter = [^\r\n\'\\] Reserved = "SELECT" | "FROM" | "INSTANCEOF" | "WHERE" %% { /* keywords */ {Reserved} { return token(TokenType.KEYWORD); } /* operators */ "(" | ")" | "{" | "}" | "[" | "]" | ";" | "," | "." | "@" | "=" | ">" | "<" | "!" | "~" | "?" | ":" { return token(TokenType.OPERATOR); } /* string literal */ \"{StringCharacter}+\" | \'{SingleCharacter}+\ { return token(TokenType.STRING); } /* numeric literals */ {DecIntegerLiteral} | {FloatLiteral} { return token(TokenType.NUMBER); } /* comments */ {Comment} { return token(TokenType.COMMENT); } /* whitespace */ {WhiteSpace}+ { /* skip */ } /* identifiers */ {Identifier} { return token(TokenType.IDENTIFIER); } } /* error fallback */ .|\n { } <> { return null; } ================================================ FILE: plugins/oqlsyntax/src/META-INF/services/jsyntaxpane.config.properties ================================================ # # OqlSyntaxKit specific jSyntaxPane settings # OqlSyntaxKit.Components = jsyntaxpane.components.PairsMarker, \ jsyntaxpane.components.TokenMarker OqlSyntaxKit.TokenMarker.TokenTypes = IDENTIFIER, TYPE, TYPE2, TYPE3 # # Performs single color selection (Default = false) # OqlSyntaxKit.SingleColorSelect = true # # DIsplaying of a right margin line. If RightMarginColumn is 0, then no margin # will be displayed OqlSyntaxKit.RightMarginColumn = 80 OqlSyntaxKit.RightMarginColor = 0xdddddd OqlSyntaxKit.Action.PARENTHISIS = jsyntaxpane.actions.PairAction, typed ( OqlSyntaxKit.Action.BRACKETS = jsyntaxpane.actions.PairAction, typed [ OqlSyntaxKit.Action.QUOTE = jsyntaxpane.actions.PairAction, typed ' OqlSyntaxKit.Action.DBL_QUOTE = jsyntaxpane.actions.PairAction, typed " OqlSyntaxKit.Action.CLOSE_CURLY = jsyntaxpane.actions.JUnindentAction, typed } OqlSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH # For completions, you have to define the Action (key to trigger completions): # JavaSyntaxKit.Action.COMPELTION = jsyntaxpane.actions.MapCompletionAction, control SPACE OqlSyntaxKit.Action.COMBO_COMPELTION = jsyntaxpane.actions.ComboCompletionAction, control SPACE # and then the specified completions map in the below file OqlSyntaxKit.Completions.File = jsyntaxpane.oqlsyntaxkit.completions # # These are the completions to be in the IntelliSense completion dialog # comma separated values. # Vertical bars: if there is one, it will position the cursor. If there are # two, they will be start and end of selection OqlSyntaxKit.COMBO_COMPELTION.Items = select, from, instanceof, where, \ heap., objectid(|), unique("|key|"), \ .forEachObject(|), .forEachClass("|callback|"), .findClass("|className|"), \ .findObject("|objectid|"), .classes(), .objects("|className|"), \ .isSubclassOf("|className|"), .isSuperClassOf("|className|"), .subclasses(), \ .superclasses(), .finalizables(), .livepaths(), .roots, \ classof(|object|), forEachReferrer(|), identical(|), \ objectid(|object|), reachables(|), referrers(|object|), \ referees(|object|), refers(|), sizeof(|), \ toHtml(|), contains(|), count(|), \ filter(|), length(|a|), map(|), max(|), \ min(|), sort(|), top(|), \ sum(|), toArray(|a|), unique(|), \ .it, .index, .array, .result # # Other Java type actions for other languages: # OqlScriptSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH ================================================ FILE: plugins/oqlsyntax/src/META-INF/services/jsyntaxpane.kitsfortypes.properties ================================================ # This file contains the default content types and the SyntaxKit class names # that will be used for them. # The keys are content types, and the values are the fully qualified class # names text/x-oql=org.graalvm.visualvm.modules.oqlsyntax.OqlSyntaxKit ================================================ FILE: plugins/oqlsyntax/src/META-INF/services/jsyntaxpane.oqlsyntaxkit.completions.properties ================================================ # This file contains the completions that will be used by the Java Syntax # editor kit. # The keys are the completion strings, and the values are the full expansion # of the text. The | character will set the cursor to that location in # completion string se=select | fr=from | ins=instanceof | wh=where | ================================================ FILE: plugins/oqlsyntax/src/org/graalvm/visualvm/modules/oqlsyntax/Bundle.properties ================================================ OpenIDE-Module-Display-Category=UI OpenIDE-Module-Long-Description=\ Provides syntax highlighting, brace matching, intendation and simple code completion OpenIDE-Module-Name=OQL Syntax Support OpenIDE-Module-Short-Description=Enhanced UI for OQL query editor ================================================ FILE: plugins/oqlsyntax/src/org/graalvm/visualvm/modules/oqlsyntax/OQLSyntaxEditor.java ================================================ /* * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.oqlsyntax; import javax.swing.JEditorPane; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.graalvm.visualvm.lib.profiler.oql.spi.*; import org.openide.util.lookup.ServiceProvider; /** * * @author Jaroslav Bachorik */ @ServiceProvider(service=OQLEditorImpl.class) public class OQLSyntaxEditor extends OQLEditorImpl { private class DocumentListenerEx implements DocumentListener { @Override public void insertUpdate(DocumentEvent e) { if (e.getDocument().getLength() > 0) { getValidationCallback(e.getDocument()).callback(true); } else { getValidationCallback(e.getDocument()).callback(false); } } @Override public void removeUpdate(DocumentEvent e) { if (e.getDocument().getLength() > 0) { getValidationCallback(e.getDocument()).callback(true); } else { getValidationCallback(e.getDocument()).callback(false); } } @Override public void changedUpdate(DocumentEvent e) { if (e.getDocument().getLength() > 0) { getValidationCallback(e.getDocument()).callback(true); } else { getValidationCallback(e.getDocument()).callback(false); } } }; @Override public JEditorPane getEditorPane() { JEditorPane pane = new JEditorPane(); pane.setContentType("text/x-oql"); pane.getDocument().addDocumentListener(new DocumentListenerEx()); return pane; } } ================================================ FILE: plugins/oqlsyntax/src/org/graalvm/visualvm/modules/oqlsyntax/OqlLexer.java ================================================ /* The following code was generated by JFlex 1.4.1 on 10/12/09 8:42 PM */ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 org.graalvm.visualvm.modules.oqlsyntax; import jsyntaxpane.DefaultLexer; import jsyntaxpane.Token; import jsyntaxpane.TokenType; /** * This class is a scanner generated by * JFlex 1.4.1 * on 10/12/09 8:42 PM from the specification file * /home/jb198685/projects/visualvm/plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/oql.flex */ public final class OqlLexer extends DefaultLexer { /** This character denotes the end of file */ public static final int YYEOF = -1; /** initial size of the lookahead buffer */ private static final int ZZ_BUFFERSIZE = 16384; /** lexical states */ public static final int YYINITIAL = 0; /** * Translates characters to character classes */ private static final String ZZ_CMAP_PACKED = "\11\6\1\3\1\2\1\0\1\3\1\1\16\6\4\0\1\35\1\34"+ "\1\15\1\0\1\5\2\0\1\16\1\34\1\34\1\0\1\14\1\34"+ "\1\4\1\12\1\0\1\7\11\10\1\34\1\34\1\34\1\34\1\34"+ "\1\34\1\34\1\31\1\5\1\22\1\5\1\13\1\11\1\5\1\33"+ "\1\27\2\5\1\21\1\26\1\30\1\25\2\5\1\24\1\20\1\23"+ "\2\5\1\32\3\5\1\34\1\17\1\34\1\0\1\5\1\0\1\31"+ "\1\5\1\22\1\5\1\13\1\11\1\5\1\33\1\27\2\5\1\21"+ "\1\26\1\30\1\25\2\5\1\24\1\20\1\23\2\5\1\32\3\5"+ "\1\34\1\0\1\34\1\34\41\6\2\0\4\5\4\0\1\5\2\0"+ "\1\6\7\0\1\5\4\0\1\5\5\0\27\5\1\0\37\5\1\0"+ "\u013f\5\31\0\162\5\4\0\14\5\16\0\5\5\11\0\1\5\21\0"+ "\130\6\5\0\23\6\12\0\1\5\13\0\1\5\1\0\3\5\1\0"+ "\1\5\1\0\24\5\1\0\54\5\1\0\46\5\1\0\5\5\4\0"+ "\202\5\1\0\4\6\3\0\105\5\1\0\46\5\2\0\2\5\6\0"+ "\20\5\41\0\46\5\2\0\1\5\7\0\47\5\11\0\21\6\1\0"+ "\27\6\1\0\3\6\1\0\1\6\1\0\2\6\1\0\1\6\13\0"+ "\33\5\5\0\3\5\15\0\4\6\14\0\6\6\13\0\32\5\5\0"+ "\13\5\16\6\7\0\12\6\4\0\2\5\1\6\143\5\1\0\1\5"+ "\10\6\1\0\6\6\2\5\2\6\1\0\4\6\2\5\12\6\3\5"+ "\2\0\1\5\17\0\1\6\1\5\1\6\36\5\33\6\2\0\3\5"+ "\60\0\46\5\13\6\1\5\u014f\0\3\6\66\5\2\0\1\6\1\5"+ "\20\6\2\0\1\5\4\6\3\0\12\5\2\6\2\0\12\6\21\0"+ "\3\6\1\0\10\5\2\0\2\5\2\0\26\5\1\0\7\5\1\0"+ "\1\5\3\0\4\5\2\0\1\6\1\5\7\6\2\0\2\6\2\0"+ "\3\6\11\0\1\6\4\0\2\5\1\0\3\5\2\6\2\0\12\6"+ "\4\5\15\0\3\6\1\0\6\5\4\0\2\5\2\0\26\5\1\0"+ "\7\5\1\0\2\5\1\0\2\5\1\0\2\5\2\0\1\6\1\0"+ "\5\6\4\0\2\6\2\0\3\6\13\0\4\5\1\0\1\5\7\0"+ "\14\6\3\5\14\0\3\6\1\0\11\5\1\0\3\5\1\0\26\5"+ "\1\0\7\5\1\0\2\5\1\0\5\5\2\0\1\6\1\5\10\6"+ "\1\0\3\6\1\0\3\6\2\0\1\5\17\0\2\5\2\6\2\0"+ "\12\6\1\0\1\5\17\0\3\6\1\0\10\5\2\0\2\5\2\0"+ "\26\5\1\0\7\5\1\0\2\5\1\0\5\5\2\0\1\6\1\5"+ "\6\6\3\0\2\6\2\0\3\6\10\0\2\6\4\0\2\5\1\0"+ "\3\5\4\0\12\6\1\0\1\5\20\0\1\6\1\5\1\0\6\5"+ "\3\0\3\5\1\0\4\5\3\0\2\5\1\0\1\5\1\0\2\5"+ "\3\0\2\5\3\0\3\5\3\0\10\5\1\0\3\5\4\0\5\6"+ "\3\0\3\6\1\0\4\6\11\0\1\6\17\0\11\6\11\0\1\5"+ "\7\0\3\6\1\0\10\5\1\0\3\5\1\0\27\5\1\0\12\5"+ "\1\0\5\5\4\0\7\6\1\0\3\6\1\0\4\6\7\0\2\6"+ "\11\0\2\5\4\0\12\6\22\0\2\6\1\0\10\5\1\0\3\5"+ "\1\0\27\5\1\0\12\5\1\0\5\5\2\0\1\6\1\5\7\6"+ "\1\0\3\6\1\0\4\6\7\0\2\6\7\0\1\5\1\0\2\5"+ "\4\0\12\6\22\0\2\6\1\0\10\5\1\0\3\5\1\0\27\5"+ "\1\0\20\5\4\0\6\6\2\0\3\6\1\0\4\6\11\0\1\6"+ "\10\0\2\5\4\0\12\6\22\0\2\6\1\0\22\5\3\0\30\5"+ "\1\0\11\5\1\0\1\5\2\0\7\5\3\0\1\6\4\0\6\6"+ "\1\0\1\6\1\0\10\6\22\0\2\6\15\0\60\5\1\6\2\5"+ "\7\6\4\0\10\5\10\6\1\0\12\6\47\0\2\5\1\0\1\5"+ "\2\0\2\5\1\0\1\5\2\0\1\5\6\0\4\5\1\0\7\5"+ "\1\0\3\5\1\0\1\5\1\0\1\5\2\0\2\5\1\0\4\5"+ "\1\6\2\5\6\6\1\0\2\6\1\5\2\0\5\5\1\0\1\5"+ "\1\0\6\6\2\0\12\6\2\0\2\5\42\0\1\5\27\0\2\6"+ "\6\0\12\6\13\0\1\6\1\0\1\6\1\0\1\6\4\0\2\6"+ "\10\5\1\0\42\5\6\0\24\6\1\0\2\6\4\5\4\0\10\6"+ "\1\0\44\6\11\0\1\6\71\0\42\5\1\0\5\5\1\0\2\5"+ "\1\0\7\6\3\0\4\6\6\0\12\6\6\0\6\5\4\6\106\0"+ "\46\5\12\0\51\5\7\0\132\5\5\0\104\5\5\0\122\5\6\0"+ "\7\5\1\0\77\5\1\0\1\5\1\0\4\5\2\0\7\5\1\0"+ "\1\5\1\0\4\5\2\0\47\5\1\0\1\5\1\0\4\5\2\0"+ "\37\5\1\0\1\5\1\0\4\5\2\0\7\5\1\0\1\5\1\0"+ "\4\5\2\0\7\5\1\0\7\5\1\0\27\5\1\0\37\5\1\0"+ "\1\5\1\0\4\5\2\0\7\5\1\0\47\5\1\0\23\5\16\0"+ "\11\6\56\0\125\5\14\0\u026c\5\2\0\10\5\12\0\32\5\5\0"+ "\113\5\3\0\3\5\17\0\15\5\1\0\4\5\3\6\13\0\22\5"+ "\3\6\13\0\22\5\2\6\14\0\15\5\1\0\3\5\1\0\2\6"+ "\14\0\64\5\40\6\3\0\1\5\3\0\2\5\1\6\2\0\12\6"+ "\41\0\3\6\2\0\12\6\6\0\130\5\10\0\51\5\1\6\126\0"+ "\35\5\3\0\14\6\4\0\14\6\12\0\12\6\36\5\2\0\5\5"+ "\u038b\0\154\5\224\0\234\5\4\0\132\5\6\0\26\5\2\0\6\5"+ "\2\0\46\5\2\0\6\5\2\0\10\5\1\0\1\5\1\0\1\5"+ "\1\0\1\5\1\0\37\5\2\0\65\5\1\0\7\5\1\0\1\5"+ "\3\0\3\5\1\0\7\5\3\0\4\5\2\0\6\5\4\0\15\5"+ "\5\0\3\5\1\0\7\5\17\0\4\6\32\0\5\6\20\0\2\5"+ "\23\0\1\5\13\0\4\6\6\0\6\6\1\0\1\5\15\0\1\5"+ "\40\0\22\5\36\0\15\6\4\0\1\6\3\0\6\6\27\0\1\5"+ "\4\0\1\5\2\0\12\5\1\0\1\5\3\0\5\5\6\0\1\5"+ "\1\0\1\5\1\0\1\5\1\0\4\5\1\0\3\5\1\0\7\5"+ "\3\0\3\5\5\0\5\5\26\0\44\5\u0e81\0\3\5\31\0\11\5"+ "\6\6\1\0\5\5\2\0\5\5\4\0\126\5\2\0\2\6\2\0"+ "\3\5\1\0\137\5\5\0\50\5\4\0\136\5\21\0\30\5\70\0"+ "\20\5\u0200\0\u19b6\5\112\0\u51a6\5\132\0\u048d\5\u0773\0\u2ba4\5\u215c\0"+ "\u012e\5\2\0\73\5\225\0\7\5\14\0\5\5\5\0\1\5\1\6"+ "\12\5\1\0\15\5\1\0\5\5\1\0\1\5\1\0\2\5\1\0"+ "\2\5\1\0\154\5\41\0\u016b\5\22\0\100\5\2\0\66\5\50\0"+ "\15\5\3\0\20\6\20\0\4\6\17\0\2\5\30\0\3\5\31\0"+ "\1\5\6\0\5\5\1\0\207\5\2\0\1\6\4\0\1\5\13\0"+ "\12\6\7\0\32\5\4\0\1\5\1\0\32\5\12\0\132\5\3\0"+ "\6\5\2\0\6\5\2\0\6\5\2\0\3\5\3\0\2\5\3\0"+ "\2\5\22\0\3\6\4\0"; /** * Translates characters to character classes */ private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); /** * Translates DFA states to action switch labels. */ private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = "\1\0\1\1\1\2\1\1\1\3\2\4\1\3\1\5"+ "\2\1\3\3\1\5\1\6\1\0\1\4\2\0\1\3"+ "\2\0\3\3\2\6\2\0\1\3\2\7\3\3\1\10"+ "\11\3"; private static int [] zzUnpackAction() { int [] result = new int[46]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; } private static int zzUnpackAction(String packed, int offset, int [] result) { int i = 0; /* index in packed string */ int j = offset; /* index in unpacked array */ int l = packed.length(); while (i < l) { int count = packed.charAt(i++); int value = packed.charAt(i++); do result[j++] = value; while (--count > 0); } return j; } /** * Translates a state to a row index in the transition table */ private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = "\0\0\0\36\0\74\0\132\0\170\0\226\0\264\0\322"+ "\0\360\0\u010e\0\u012c\0\u014a\0\u0168\0\u0186\0\36\0\u01a4"+ "\0\226\0\36\0\u01c2\0\u01e0\0\u01fe\0\u021c\0\u023a\0\u0258"+ "\0\u0276\0\u0294\0\u02b2\0\36\0\u02d0\0\u02ee\0\u030c\0\36"+ "\0\u023a\0\u032a\0\u0348\0\u0366\0\170\0\u0384\0\u03a2\0\u03c0"+ "\0\u03de\0\u03fc\0\u041a\0\u0438\0\u0456\0\u0474"; private static int [] zzUnpackRowMap() { int [] result = new int[46]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; } private static int zzUnpackRowMap(String packed, int offset, int [] result) { int i = 0; /* index in packed string */ int j = offset; /* index in unpacked array */ int l = packed.length(); while (i < l) { int high = packed.charAt(i++) << 16; result[j++] = high | packed.charAt(i++); } return j; } /** * The transition table of the DFA */ private static final int [] ZZ_TRANS = zzUnpackTrans(); private static final String ZZ_TRANS_PACKED_0 = "\1\2\3\3\1\4\1\5\1\2\1\6\1\7\1\10"+ "\1\11\1\5\1\2\1\12\1\13\1\2\1\14\6\5"+ "\1\15\2\5\1\16\1\5\1\17\1\3\37\0\3\3"+ "\31\0\1\3\4\0\1\20\36\0\5\5\1\0\1\5"+ "\4\0\14\5\11\0\2\21\1\22\1\23\1\24\31\0"+ "\2\7\1\22\1\23\1\24\27\0\5\5\1\0\1\5"+ "\4\0\4\5\1\25\7\5\11\0\2\23\25\0\1\26"+ "\2\0\12\26\1\0\1\26\1\0\16\26\1\27\2\0"+ "\13\27\2\0\16\27\5\0\5\5\1\0\1\30\4\0"+ "\14\5\7\0\5\5\1\0\1\5\4\0\10\5\1\31"+ "\3\5\7\0\5\5\1\0\1\5\4\0\13\5\1\32"+ "\2\0\1\20\1\33\1\34\33\20\7\0\2\23\1\22"+ "\1\0\1\24\26\0\1\35\2\0\2\36\3\0\1\35"+ "\26\0\5\5\1\0\1\5\4\0\5\5\1\37\6\5"+ "\2\0\1\26\2\0\12\26\1\40\1\26\1\0\16\26"+ "\1\27\2\0\13\27\2\0\15\27\1\41\5\0\5\5"+ "\1\0\1\5\4\0\1\5\1\42\12\5\7\0\5\5"+ "\1\0\1\5\4\0\1\43\13\5\7\0\5\5\1\0"+ "\1\44\4\0\14\5\4\0\1\34\42\0\2\36\34\0"+ "\2\36\1\22\31\0\5\5\1\0\1\5\4\0\6\5"+ "\1\45\5\5\7\0\5\5\1\0\1\46\4\0\14\5"+ "\7\0\5\5\1\0\1\5\4\0\3\5\1\47\10\5"+ "\7\0\5\5\1\0\1\5\4\0\4\5\1\50\7\5"+ "\7\0\5\5\1\0\1\5\4\0\2\5\1\51\11\5"+ "\7\0\5\5\1\0\1\5\4\0\11\5\1\52\2\5"+ "\7\0\5\5\1\0\1\45\4\0\14\5\7\0\5\5"+ "\1\0\1\5\4\0\3\5\1\45\10\5\7\0\5\5"+ "\1\0\1\5\4\0\10\5\1\53\3\5\7\0\5\5"+ "\1\0\1\5\4\0\2\5\1\54\11\5\7\0\5\5"+ "\1\0\1\55\4\0\14\5\7\0\5\5\1\0\1\5"+ "\4\0\5\5\1\56\6\5\7\0\4\5\1\45\1\0"+ "\1\5\4\0\14\5\2\0"; private static int [] zzUnpackTrans() { int [] result = new int[1170]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; } private static int zzUnpackTrans(String packed, int offset, int [] result) { int i = 0; /* index in packed string */ int j = offset; /* index in unpacked array */ int l = packed.length(); while (i < l) { int count = packed.charAt(i++); int value = packed.charAt(i++); value--; do result[j++] = value; while (--count > 0); } return j; } /* error codes */ private static final int ZZ_UNKNOWN_ERROR = 0; private static final int ZZ_NO_MATCH = 1; private static final int ZZ_PUSHBACK_2BIG = 2; /* error messages for the codes above */ private static final String ZZ_ERROR_MSG[] = { "Unkown internal scanner error", "Error: could not match input", "Error: pushback value was too large" }; /** * ZZ_ATTRIBUTE[aState] contains the attributes of state aState */ private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = "\1\0\1\11\14\1\1\11\1\1\1\0\1\11\2\0"+ "\1\1\2\0\4\1\1\11\2\0\1\1\1\11\16\1"; private static int [] zzUnpackAttribute() { int [] result = new int[46]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; } private static int zzUnpackAttribute(String packed, int offset, int [] result) { int i = 0; /* index in packed string */ int j = offset; /* index in unpacked array */ int l = packed.length(); while (i < l) { int count = packed.charAt(i++); int value = packed.charAt(i++); do result[j++] = value; while (--count > 0); } return j; } /** the input device */ private java.io.Reader zzReader; /** the current state of the DFA */ private int zzState; /** the current lexical state */ private int zzLexicalState = YYINITIAL; /** this buffer contains the current text to be matched and is the source of the yytext() string */ private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; /** the textposition at the last accepting state */ private int zzMarkedPos; /** the textposition at the last state to be included in yytext */ private int zzPushbackPos; /** the current text position in the buffer */ private int zzCurrentPos; /** startRead marks the beginning of the yytext() string in the buffer */ private int zzStartRead; /** endRead marks the last character in the buffer, that has been read from input */ private int zzEndRead; /** number of newlines encountered up to the start of the matched text */ private int yyline; /** the number of characters up to the start of the matched text */ private int yychar; /** * the number of characters from the last newline up to the start of the * matched text */ private int yycolumn; /** * zzAtBOL == true <=> the scanner is currently at the beginning of a line */ private boolean zzAtBOL = true; /** zzAtEOF == true <=> the scanner is at the EOF */ private boolean zzAtEOF; /* user code: */ /** * Default constructor is needed as we will always call the yyreset */ public OqlLexer() { super(); } /** * Helper method to create and return a new Token from of TokenType */ private Token token(TokenType type) { return new Token(type, yychar, yylength()); } /** * Creates a new scanner * There is also a java.io.InputStream version of this constructor. * * @param in the java.io.Reader to read input from. */ public OqlLexer(java.io.Reader in) { this.zzReader = in; } /** * Creates a new scanner. * There is also java.io.Reader version of this constructor. * * @param in the java.io.Inputstream to read input from. */ public OqlLexer(java.io.InputStream in) { this(new java.io.InputStreamReader(in)); } /** * Unpacks the compressed character translation table. * * @param packed the packed character translation table * @return the unpacked character translation table */ private static char [] zzUnpackCMap(String packed) { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ while (i < 1788) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); } return map; } /** * Refills the input buffer. * * @return false, iff there was new input. * * @exception java.io.IOException if any I/O-Error occurs */ private boolean zzRefill() throws java.io.IOException { /* first: make room (if you can) */ if (zzStartRead > 0) { System.arraycopy(zzBuffer, zzStartRead, zzBuffer, 0, zzEndRead-zzStartRead); /* translate stored positions */ zzEndRead-= zzStartRead; zzCurrentPos-= zzStartRead; zzMarkedPos-= zzStartRead; zzPushbackPos-= zzStartRead; zzStartRead = 0; } /* is the buffer big enough? */ if (zzCurrentPos >= zzBuffer.length) { /* if not: blow it up */ char newBuffer[] = new char[zzCurrentPos*2]; System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); zzBuffer = newBuffer; } /* finally: fill the buffer with new input */ int numRead = zzReader.read(zzBuffer, zzEndRead, zzBuffer.length-zzEndRead); if (numRead < 0) { return true; } else { zzEndRead+= numRead; return false; } } /** * Closes the input stream. */ public final void yyclose() throws java.io.IOException { zzAtEOF = true; /* indicate end of file */ zzEndRead = zzStartRead; /* invalidate buffer */ if (zzReader != null) zzReader.close(); } /** * Resets the scanner to read from a new input stream. * Does not close the old reader. * * All internal variables are reset, the old input stream * cannot be reused (internal buffer is discarded and lost). * Lexical state is set to ZZ_INITIAL. * * @param reader the new input stream */ public final void yyreset(java.io.Reader reader) { zzReader = reader; zzAtBOL = true; zzAtEOF = false; zzEndRead = zzStartRead = 0; zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; yyline = yychar = yycolumn = 0; zzLexicalState = YYINITIAL; } /** * Returns the current lexical state. */ public final int yystate() { return zzLexicalState; } /** * Enters a new lexical state * * @param newState the new lexical state */ public final void yybegin(int newState) { zzLexicalState = newState; } /** * Returns the text matched by the current regular expression. */ public final String yytext() { return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); } /** * Returns the character at position pos from the * matched text. * * It is equivalent to yytext().charAt(pos), but faster * * @param pos the position of the character to fetch. * A value from 0 to yylength()-1. * * @return the character at position pos */ public final char yycharat(int pos) { return zzBuffer[zzStartRead+pos]; } /** * Returns the length of the matched text region. */ public final int yylength() { return zzMarkedPos-zzStartRead; } /** * Reports an error that occured while scanning. * * In a wellformed scanner (no or only correct usage of * yypushback(int) and a match-all fallback rule) this method * will only be called with things that "Can't Possibly Happen". * If this method is called, something is seriously wrong * (e.g. a JFlex bug producing a faulty scanner etc.). * * Usual syntax/scanner level error handling should be done * in error fallback rules. * * @param errorCode the code of the errormessage to display */ private void zzScanError(int errorCode) { String message; try { message = ZZ_ERROR_MSG[errorCode]; } catch (ArrayIndexOutOfBoundsException e) { message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; } throw new Error(message); } /** * Pushes the specified amount of characters back into the input stream. * * They will be read again by then next call of the scanning method * * @param number the number of characters to be read again. * This number must not be greater than yylength()! */ public void yypushback(int number) { if ( number > yylength() ) zzScanError(ZZ_PUSHBACK_2BIG); zzMarkedPos -= number; } /** * Resumes scanning until the next regular expression is matched, * the end of input is encountered or an I/O-Error occurs. * * @return the next token * @exception java.io.IOException if any I/O-Error occurs */ public Token yylex() throws java.io.IOException { int zzInput; int zzAction; // cached fields: int zzCurrentPosL; int zzMarkedPosL; int zzEndReadL = zzEndRead; char [] zzBufferL = zzBuffer; char [] zzCMapL = ZZ_CMAP; int [] zzTransL = ZZ_TRANS; int [] zzRowMapL = ZZ_ROWMAP; int [] zzAttrL = ZZ_ATTRIBUTE; while (true) { zzMarkedPosL = zzMarkedPos; yychar+= zzMarkedPosL-zzStartRead; zzAction = -1; zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; zzState = zzLexicalState; zzForAction: { while (true) { if (zzCurrentPosL < zzEndReadL) zzInput = zzBufferL[zzCurrentPosL++]; else if (zzAtEOF) { zzInput = YYEOF; break zzForAction; } else { // store back cached positions zzCurrentPos = zzCurrentPosL; zzMarkedPos = zzMarkedPosL; boolean eof = zzRefill(); // get translated positions and possibly new buffer zzCurrentPosL = zzCurrentPos; zzMarkedPosL = zzMarkedPos; zzBufferL = zzBuffer; zzEndReadL = zzEndRead; if (eof) { zzInput = YYEOF; break zzForAction; } else { zzInput = zzBufferL[zzCurrentPosL++]; } } int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; if (zzNext == -1) break zzForAction; zzState = zzNext; int zzAttributes = zzAttrL[zzState]; if ( (zzAttributes & 1) == 1 ) { zzAction = zzState; zzMarkedPosL = zzCurrentPosL; if ( (zzAttributes & 8) == 8 ) break zzForAction; } } } // store back cached position zzMarkedPos = zzMarkedPosL; switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { case 7: { return token(TokenType.STRING); } case 9: break; case 8: { return token(TokenType.KEYWORD); } case 10: break; case 5: { return token(TokenType.OPERATOR); } case 11: break; case 2: { /* skip */ } case 12: break; case 4: { return token(TokenType.NUMBER); } case 13: break; case 3: { return token(TokenType.IDENTIFIER); } case 14: break; case 6: { return token(TokenType.COMMENT); } case 15: break; case 1: { } case 16: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { zzAtEOF = true; { return null; } } else { zzScanError(ZZ_NO_MATCH); } } } } } ================================================ FILE: plugins/oqlsyntax/src/org/graalvm/visualvm/modules/oqlsyntax/OqlSyntaxKit.java ================================================ /* * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.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 org.graalvm.visualvm.modules.oqlsyntax; import jsyntaxpane.DefaultSyntaxKit; /** * * @author Ayman Al-Sairafi */ public class OqlSyntaxKit extends DefaultSyntaxKit { public OqlSyntaxKit() { super(new OqlLexer()); } } ================================================ FILE: plugins/saplugin/build.xml ================================================ Builds, tests, and runs the project SAPlugin. ================================================ FILE: plugins/saplugin/manifest.mf ================================================ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: true OpenIDE-Module: org.graalvm.visualvm.modules.saplugin/2 OpenIDE-Module-Install: org/graalvm/visualvm/modules/saplugin/Installer.class OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/saplugin/Bundle.properties OpenIDE-Module-Specification-Version: 2.0 ================================================ FILE: plugins/saplugin/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/saplugin/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=3999dcf2 build.xml.script.CRC32=14b0729f build.xml.stylesheet.CRC32=79c3b980 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=3999dcf2 nbproject/build-impl.xml.script.CRC32=e8e935b2 nbproject/build-impl.xml.stylesheet.CRC32=deb65f65 ================================================ FILE: plugins/saplugin/nbproject/project.properties ================================================ # # Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8 auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80 auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=default javac.source=1.5 javac.compilerargs=-Xlint -Xlint:-serial license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Poonam Bajaj nbm.needs.restart=true module.javadoc.packages=org.graalvm.visualvm.modules.saplugin.* ================================================ FILE: plugins/saplugin/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.saplugin org.graalvm.visualvm.application 2 2.0 org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.coredump 2 2.0 org.graalvm.visualvm.host 2 2.0 org.graalvm.visualvm.tools 2 2.0 org.openide.dialogs 7.8.1 org.openide.modules 7.3.1 org.openide.util 9.8 org.openide.util.ui 9.8 ================================================ FILE: plugins/saplugin/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/Agent.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import org.graalvm.visualvm.core.datasource.DataSource; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Proxy; import java.net.MalformedURLException; import java.util.Map; import java.util.HashMap; import org.openide.util.Exceptions; class Agent { private static Map agentMap = new HashMap(); private static Map classloaderMap = new HashMap(); static Agent createAgent(File jdkHome,File saJarFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException { /*synchronized (agentMap) { Agent agent = agentMap.get(saJarFile); if (agent == null) { agent = new Agent(jdkHome,saJarFile); agentMap.put(saJarFile,agent); } return agent; } */ Agent agent = new Agent(jdkHome,saJarFile); return agent; } private SAWrapper saClassLoader = null; //private final SAObject bugspotAgent; private final SAObject hotspotAgent; private VM vm; private Arguments args; private Object saListener = null; private Agent(File jdkHome,File saJarFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException { // saClassLoader = classloaderMap.get(jdkHome); // if (saClassLoader == null) { saClassLoader = new SAWrapper(jdkHome,saJarFile); // classloaderMap.put(jdkHome, saClassLoader); // } hotspotAgent = new SAObject(saClassLoader.HotspotAgent().newInstance()); } boolean attach(int pid) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException { hotspotAgent.invoke("attach",pid); // NOI18N return true; //isJavaMode(); } boolean attach(String executable,String coredump) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException { hotspotAgent.invoke("attach",executable,coredump); // NOI18N return true; } boolean attach(String remoteServer) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException { hotspotAgent.invoke("attach",remoteServer); // NOI18N return true; } void detach() throws IllegalAccessException, InvocationTargetException { hotspotAgent.invoke("detach"); // NOI18N } VM getVM() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (vm == null) { Class vmClass = saClassLoader.VM(); Object saVM = vmClass.getMethod("getVM").invoke(null); // NOI18N vm = new VM(saVM); } return vm; } Arguments getArguments() throws ClassNotFoundException { if (args == null) { args = new Arguments(saClassLoader.Arguments()); } return args; } SAObject getHeapHprofBinWriter() throws ClassNotFoundException, InstantiationException, IllegalAccessException { return new SAObject(saClassLoader.HeapHprofBinWriter().newInstance()); } /* private boolean isJavaMode() throws IllegalAccessException, InvocationTargetException { Boolean b = (Boolean) hotspotAgent.invoke("isJavaMode"); // NOI18N return b.booleanValue(); } */ ///////////////////////////////////////////////// JavaStackTracePanel createJavaStackTracePanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException { return new JavaStackTracePanel(saClassLoader.JavaStackTracePanel().newInstance()); } JavaThreadsPanel createJavaThreadsPanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException { return new JavaThreadsPanel(saClassLoader.JavaThreadsPanel().newInstance()); } CodeViewerPanel createCodeViewerPanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException { return new CodeViewerPanel(saClassLoader.CodeViewerPanel().newInstance()); } FindPointerPanel createFindPointerPanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException { return new FindPointerPanel(saClassLoader.FindPanel().newInstance()); } FindInHeapPanel createFindInHeapPanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException { return new FindInHeapPanel(saClassLoader.FindInHeapPanel().newInstance()); } FindInCodeCachePanel createFindInCodeCachePanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException { return new FindInCodeCachePanel(saClassLoader.FindInCodeCachePanel().newInstance()); } Inspector createOopInspector() throws ClassNotFoundException, InstantiationException, IllegalAccessException { return new Inspector(saClassLoader.OopInspector().newInstance()); } Inspector createOopInspector(Object root) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException { Constructor con = saClassLoader.OopInspector().getDeclaredConstructor(new Class[] { saClassLoader.SimpleTreeNode()}); Object instance = null; try { instance = con.newInstance(root); } catch (IllegalArgumentException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } return new Inspector(instance); } OopTreeNodeAdapter createOopTreeNodeAdapter(Object oopObject, Object fieldID) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException { //return new OopTreeNodeAdapter(saClassLoader.OopTreeNodeAdapter().newInstance()); Constructor con = saClassLoader.OopTreeNodeAdapter().getDeclaredConstructor(new Class[] { saClassLoader.Oop(), saClassLoader.FieldIdentifier() }); Object instance = null; try { instance = con.newInstance(new Object[]{oopObject, fieldID}); } catch (IllegalArgumentException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } return new OopTreeNodeAdapter(instance); } Object SAListener(SAModelImpl model) throws ClassNotFoundException, InstantiationException, IllegalAccessException { if (saListener == null) { saListener = Proxy.newProxyInstance(saClassLoader.loader, new Class[] {saClassLoader.SAListener()}, new ProxyListener(model)); } return saListener; } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/Arguments.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; class Arguments { private final Class arguments; Arguments(Class args) { arguments = args; } String getJVMFlags() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return (String) arguments.getMethod("getJVMFlags").invoke(null); // NOI18N } String getJVMArgs() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException{ return (String) arguments.getMethod("getJVMArgs").invoke(null); // NOI18N } String getJavaCommand() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return (String) arguments.getMethod("getJavaCommand").invoke(null); // NOI18N } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/Bundle.properties ================================================ OpenIDE-Module-Display-Category=Tools OpenIDE-Module-Long-Description=\ SAPlugin makes key features of Serviceability Agent (SA) available in VisualVM. \ Serviceability Agent is a snapshot debugger for Hotspot VM. \ It can be used to explore Java Objects present in Java Heap, and Hotspot Data Structures, both in live processes as well as in core files. OpenIDE-Module-Name=SAPlugin OpenIDE-Module-Short-Description=Serviceability Agent Plugin ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/CodeViewerPanel.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; import javax.swing.JPanel; import org.openide.util.Exceptions; /** * * @author poonam */ public class CodeViewerPanel { public final SAObject codeViewer; public CodeViewerPanel(Object panel) { this.codeViewer = new SAObject(panel); } public JPanel getPanel() { return (JPanel)codeViewer.instance; } public void setListener(Object o) { try { codeViewer.invoke("addPanelListener", o); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/FindInCodeCachePanel.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; import javax.swing.JPanel; import org.openide.util.Exceptions; /** * * @author poonam */ public class FindInCodeCachePanel { public final SAObject findInCodeCache; public FindInCodeCachePanel(Object panel) { this.findInCodeCache = new SAObject(panel); } public JPanel getPanel() { return (JPanel)findInCodeCache.instance; } public void setListener(Object o) { try { findInCodeCache.invoke("addPanelListener", o); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/FindInHeapPanel.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; import javax.swing.JPanel; import org.openide.util.Exceptions; /** * * @author poonam */ public class FindInHeapPanel { public final SAObject findInHeapPanel; public FindInHeapPanel(Object panel) { this.findInHeapPanel = new SAObject(panel); } public JPanel getPanel() { return (JPanel)findInHeapPanel.instance; } public void setListener(Object o) { try { findInHeapPanel.invoke("addPanelListener", o); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/FindPointerPanel.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; import javax.swing.JPanel; import org.openide.util.Exceptions; /** * * @author poonam */ public class FindPointerPanel { public final SAObject findPanel; public FindPointerPanel(Object panel) { this.findPanel = new SAObject(panel); } public JPanel getPanel() { return (JPanel)findPanel.instance; } public void setListener(Object o) { try { findPanel.invoke("addPanelListener", o); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/Inspector.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; import javax.swing.JPanel; import org.openide.util.Exceptions; /** * * @author poonam */ public class Inspector { public final SAObject inspector; public Inspector(Object panel) { this.inspector = new SAObject(panel); } public JPanel getPanel() { return (JPanel)inspector.instance; } public void setListener(Object o) { try { inspector.invoke("addPanelListener", o); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/Installer.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import org.graalvm.visualvm.tools.sa.SaModelFactory; import org.openide.modules.ModuleInstall; /** * Manages a module's lifecycle. Remember that an installer is optional and * often not needed at all. */ public class Installer extends ModuleInstall { @Override public void restored() { SaModelFactory.getDefault().registerProvider(new SAModelProvider()); new SAViewProvider().initialize(); } @Override public void uninstalled() { SAViewProvider.unregister(); } @Override public boolean closing() { SAView.isClosing = true; return super.closing(); } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/JavaStackTracePanel.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; import javax.swing.JPanel; import org.openide.util.Exceptions; /** * * @author poonam */ public class JavaStackTracePanel { private SAObject stackTracePanel; public JavaStackTracePanel(Object panel) { this.stackTracePanel = new SAObject(panel); } public JPanel getPanel() { return (JPanel)stackTracePanel.instance; } public void setJavaThread(Object thread) { try { stackTracePanel.invoke("setJavaThread", thread); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/JavaThreadsPanel.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; import javax.swing.JPanel; import org.openide.util.Exceptions; /** * * @author poonam */ public class JavaThreadsPanel { private SAObject threadsPanel; public JavaThreadsPanel(Object panel) { this.threadsPanel = new SAObject(panel); // threadsPanel.invoke("addListener", ) } public JPanel getPanel() { return (JPanel)threadsPanel.instance; } public void setListener(Object o) { try { threadsPanel.invoke("addPanelListener", o); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } public void removeListener(Object o) { try { threadsPanel.invoke("removePanelListener", o); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/OopInspectorView.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import java.awt.BorderLayout; import javax.swing.JComponent; import javax.swing.JPanel; /** * * @author poonam */ public class OopInspectorView extends JComponent { private JPanel inspectorPanel; private String caption; private int position; private SAModelImpl model; private DataViewComponent.DetailsView detailView; public OopInspectorView(SAModelImpl model, String caption, int position) { this.model = model; this.caption = caption; this.position = position; detailView = null; initComponents(); } public DataViewComponent.DetailsView getDetailsView() { if (detailView == null) { detailView = new DataViewComponent.DetailsView(caption, null, position, this, null); } return detailView; } public void refresh(Object oop) { this.removeAll(); Inspector inspector = null; if (oop != null) inspector = model.createOopInspector(model.createOopTreeNodeAdapter(oop, null).treeNode.instance); else inspector = model.createOopInspector(); inspector.setListener(model.getSAListener()); inspectorPanel = inspector.getPanel(); add(inspectorPanel, BorderLayout.CENTER); } private void initComponents() { setLayout(new BorderLayout()); } public void remove() { this.removeAll(); } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/OopTreeNodeAdapter.java ================================================ /* * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; import javax.swing.JPanel; import org.openide.util.Exceptions; /** * * @author poonam */ public class OopTreeNodeAdapter { public final SAObject treeNode; public OopTreeNodeAdapter(Object node) { this.treeNode = new SAObject(node); } public JPanel getPanel() { return (JPanel)treeNode.instance; } public void setListener(Object o) { try { treeNode.invoke("addPanelListener", o); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/ProxyListener.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.*; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.util.Exceptions; /** * * @author poonam */ public class ProxyListener implements java.lang.reflect.InvocationHandler { SAModelImpl model = null; public ProxyListener(SAModelImpl model) { this.model = model; } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { Object result = null; try { System.out.print("begin method " + m.getName() + "("); for(int i=0; i0) System.out.print(","); System.out.print(" " + args[i].toString()); } System.out.println(" )"); if (m.getName().equals("showThreadOopInspector")) { showThreadOopInspector(args[0]); } else if (m.getName().equals("showInspector")) { showInspector(args[0]); } else if (m.getName().equals("showThreadStackMemory")) { showStackMemoryPanel(args[0]); } else if (m.getName().equals("showThreadInfo")) { } else if (m.getName().equals("showJavaStackTrace")) { showJavaStackTrace(args[0]); } else if (m.getName().equals("showCodeViewer")) { } else if (m.getName().equals("showLiveness")) { showLivenessPanel(args[0]); } } catch (Exception e) { throw new RuntimeException ("unexpected invocation exception: " + e.getMessage()); } finally { System.out.println( "end method " + m.getName()); } return result; } void showJavaStackTrace(Object thread) { SAView view = model.getView(); view.updateStackTraceView(thread); } void showLivenessPanel(Object o) { NotifyDescriptor nd = new NotifyDescriptor.Message("Not yet implemented", NotifyDescriptor.INFORMATION_MESSAGE) ; DialogDisplayer.getDefault().notify(nd); } void showStackMemoryPanel(Object thread) { NotifyDescriptor nd = new NotifyDescriptor.Message("Not yet implemented", NotifyDescriptor.INFORMATION_MESSAGE) ; DialogDisplayer.getDefault().notify(nd); } void showThreadOopInspector(Object o) { SAObject thread = new SAObject(o); SAObject threadObj = null; try { threadObj = thread.invokeSA("getThreadObj"); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } catch (InvocationTargetException ex) { Exceptions.printStackTrace(ex); } showInspector(threadObj.instance); } public void showInspector(Object oopObject) { SAView view = model.getView(); view.updateOopInspectorView(oopObject); } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAModelImpl.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import org.graalvm.visualvm.tools.sa.SaModel; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.util.Properties; import org.openide.ErrorManager; import org.openide.util.Exceptions; public class SAModelImpl extends SaModel { private Agent agent; private int pid; String executable; String core; private Properties sysProp; private String jvmFlags; private String jvmArgs; private String commandLine; private SAView view; SAModelImpl(File jdkHome,File sajar,int id) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException, InvocationTargetException, NoSuchMethodException { agent = Agent.createAgent(jdkHome,sajar); pid = id; //readData(); } SAModelImpl(File jdkHome,File sajar,File execFile,File coreFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, MalformedURLException, NoSuchMethodException { agent = Agent.createAgent(jdkHome,sajar); executable = execFile.getAbsolutePath(); core = coreFile.getAbsolutePath(); //readData(); } public Properties getSystemProperties() { return sysProp; } public boolean takeHeapDump(String file){ try { synchronized (agent) { try { if (attach()) { SAObject hprofWrite = agent.getHeapHprofBinWriter(); hprofWrite.invoke("write",file); // NOI18N return true; } } finally { agent.detach(); } } } catch (Exception ex) { Throwable e = ex.getCause(); ErrorManager.getDefault().notify(e == null ? ex : e); } return false; } public String takeThreadDump(){ try { synchronized (agent) { try { if (attach()) { return new StackTrace(agent.getVM()).getStackTrace(); } } finally { agent.detach(); } } } catch (Exception ex) { Throwable e = ex.getCause(); ErrorManager.getDefault().notify(e == null ? ex : e); } return null; } public String getJvmFlags() { return jvmFlags; } public String getJvmArgs() { return jvmArgs; } public String getJavaCommand() { return commandLine; } public boolean attach() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException { if (core == null) { return agent.attach(pid); } return agent.attach(executable,core); } public void detach() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException { agent.detach(); } public Agent getAgent() { return agent; } public void readData() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { synchronized (agent) { //try { // if (attach()) { Arguments args = agent.getArguments(); jvmFlags = args.getJVMFlags(); jvmArgs = args.getJVMArgs(); commandLine = args.getJavaCommand(); sysProp = (Properties)agent.getVM().getSystemProperties().clone(); // } // } finally { // agent.detach(); // } } } //------------------------------------------------------------// public Inspector createOopInspector() { Inspector obj = null; try { obj = agent.createOopInspector(); } catch (Exception e) { } return obj; } public Inspector createOopInspector(Object o) { Inspector obj = null; try { obj = agent.createOopInspector(o); } catch (Exception e) { } return obj; } public JavaStackTracePanel createJavaStackTracePanel() { JavaStackTracePanel obj = null; try { obj = agent.createJavaStackTracePanel(); } catch (Exception e) { } return obj; } public JavaThreadsPanel createJavaThreadsPanel() { JavaThreadsPanel obj = null; try { obj = agent.createJavaThreadsPanel(); } catch (Exception e) { } return obj; } public CodeViewerPanel createCodeViewerPanel() { CodeViewerPanel obj = null; try { obj = agent.createCodeViewerPanel(); } catch (Exception e) { } return obj; } public FindPointerPanel createFindPointerPanel() { FindPointerPanel obj = null; try { obj = agent.createFindPointerPanel(); } catch (Exception e) { } return obj; } public FindInHeapPanel createFindInHeapPanel() { FindInHeapPanel obj = null; try { obj = agent.createFindInHeapPanel(); } catch (Exception e) { } return obj; } public FindInCodeCachePanel createFindInCodeCachePanel() { FindInCodeCachePanel obj = null; try { obj = agent.createFindInCodeCachePanel(); } catch (Exception e) { } return obj; } public OopTreeNodeAdapter createOopTreeNodeAdapter(Object oopObject, Object fieldID) { OopTreeNodeAdapter obj = null; try { obj = agent.createOopTreeNodeAdapter(oopObject, fieldID); } catch (Exception e) { } return obj; } public Object getSAListener() { Object obj = null; try { obj = agent.SAListener(this); } catch (ClassNotFoundException ex) { Exceptions.printStackTrace(ex); } catch (InstantiationException ex) { Exceptions.printStackTrace(ex); } catch (IllegalAccessException ex) { Exceptions.printStackTrace(ex); } return obj; } public SAView getView() { return view; } public void setView(SAView view) { this.view = view; } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAModelProvider.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.model.AbstractModelProvider; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.coredump.CoreDump; import org.graalvm.visualvm.host.Host; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory; import org.graalvm.visualvm.tools.sa.SaModel; import java.io.File; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class SAModelProvider extends AbstractModelProvider { private static final Logger LOGGER = Logger.getLogger(SAModelProvider.class.getName()); private static final String SA_JAR = "lib/sa-jdi.jar"; // NOI18N SAModelProvider() { } public SaModel createModelFor(DataSource ds) { if (ds instanceof Application) { Application app = (Application) ds; if (Host.LOCALHOST.equals(app.getHost())) { JvmJvmstatModel jvmstat = JvmJvmstatModelFactory.getJvmstatModelFor(app); File jdkHome = new File(jvmstat.getJavaHome()); if ("jre".equals(jdkHome.getName())) { jdkHome = jdkHome.getParentFile(); } File saJar = getSaJar(jdkHome); if (saJar == null) { return null; } try { return new SAModelImpl(jdkHome,saJar,app.getPid()); } catch (Exception ex) { LOGGER.log(Level.INFO, "Error getting SA agent", ex); // NOI18N } } } else if (ds instanceof CoreDump) { CoreDump coredump = (CoreDump) ds; File executable = new File(coredump.getExecutable()); File coreFile = coredump.getFile(); if (executable.exists() && coreFile.exists()) { File jdkHome = executable.getParentFile().getParentFile(); File saJar = getSaJar(jdkHome); if (saJar == null) { return null; } try { return new SAModelImpl(jdkHome,saJar,executable,coreFile); } catch (Exception ex) { LOGGER.log(Level.INFO, "Unable to retrieve SA agent", ex); // NOI18N } } } return null; } static File getSaJar(File jdkHome) { File saJar = new File(jdkHome,SA_JAR); try { if (saJar.exists()) { return saJar.getCanonicalFile(); } saJar = new File( SA_JAR); //Changed this if (saJar.exists()) { return saJar.getCanonicalFile(); } } catch (IOException ex) { LOGGER.log(Level.INFO, saJar.getPath(), ex); } return null; } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAObject.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; class SAObject { final Object instance; Map> methodCache; private static Map primitiveTypes; static { primitiveTypes = new HashMap(); primitiveTypes.put(Integer.class,Integer.TYPE); } SAObject(Object i) { instance = i; if (i != null) { methodCache = new HashMap(); Method[] methods = i.getClass().getMethods(); for (int j = 0; j < methods.length; j++) { Method method = methods[j]; String name = method.getName(); int pars = method.getParameterTypes().length; String id = methodId(name,pars); List mlist = Collections.singletonList(method); List oldlist = methodCache.put(id,mlist); if (oldlist != null) { List unitedList = new ArrayList(mlist); unitedList.addAll(oldlist); methodCache.put(id,unitedList); } } } } boolean isNull() { return instance == null; } Object invoke(String methodName,Object... parameters) throws IllegalAccessException, InvocationTargetException { String mid = methodId(methodName,parameters.length); List methods = methodCache.get(mid); Method method = null; if (methods == null) { throw new IllegalAccessException("No method "+mid); // NOI18N } if (methods.size()==1) { method = methods.get(0); } else { Class[] parClasses = new Class[parameters.length]; for (int i = 0; i < parameters.length; i++) { Class cl = parameters[i].getClass(); if (primitiveTypes.containsKey(cl)) { cl = primitiveTypes.get(cl); } parClasses[i] = cl; } for (Method m : methods) { if (Arrays.deepEquals(m.getParameterTypes(),parClasses)) { method = m; break; } } } if (method == null) { throw new IllegalArgumentException(instance+" "+methodName+" "+Arrays.toString(parameters)); } return method.invoke(instance,parameters); } SAObject invokeSA(String methodName,Object... parameters) throws IllegalAccessException, InvocationTargetException { return new SAObject(invoke(methodName,parameters)); } private static String methodId(String name,int pars) { return name.concat("#").concat(Integer.toString(pars)); // NOI18N } public String toString() { if (instance != null) { return instance.toString(); } return ""; // NOI18N } public int hashCode() { if (instance == null) return 0; return instance.hashCode(); } public boolean equals(Object obj) { if (obj instanceof SAObject) { SAObject saobj = (SAObject) obj; if (instance == null) { return saobj.instance == null; } return instance.equals(saobj.instance); } return false; } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAPluginClassLoader.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.io.File; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; /** * * @author poonam */ class SAPluginClassLoader extends URLClassLoader { private static ClassLoader parent; private boolean classPathSet; private File libraryPath; SAPluginClassLoader(ClassLoader parent) { super(new URL[0], parent); this.parent = parent; } SAPluginClassLoader(ClassLoader parent, File jdkHome, File saJarFile) { this(parent); this.classPathSet = true; try { addURL(saJarFile.toURI().toURL()); } catch(MalformedURLException mue) { throw new RuntimeException(mue); } libraryPath = new File(jdkHome, "jre/bin/"); } public synchronized Class loadClass(String name) throws ClassNotFoundException { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { /* If we are loading any class in 'sun.jvm.hotspot.' or any of the * sub-packages (except for 'debugger' sub-pkg. please refer below), * we load it by 'this' loader. Or else, we forward the request to * 'parent' loader, system loader etc. (rest of the code follows * the patten in java.lang.ClassLoader.loadClass). * * 'sun.jvm.hotspot.debugger.' and sub-package classes are * also loaded by parent loader. This is done for two reasons: * * 1. to avoid code bloat by too many classes. * 2. to avoid loading same native library multiple times * from multiple class loaders (which results in getting a * UnsatisifiedLinkageError from System.loadLibrary). */ if ( ( name.startsWith("sun.jvm.hotspot.") || name.startsWith("com.sun.java.swing.") ) && !name.startsWith("sun.jvm.hotspot.debugger.")) { return findClass(name); } if (parent != null) { c = parent.loadClass(name); } else { c = findSystemClass(name); } } return c; } protected Class findClass(String name) throws ClassNotFoundException { if (classPathSet) { return super.findClass(name); } else { byte[] b = null; try { InputStream in = getResourceAsStream(name.replace('.', '/') + ".class"); // Read until end of stream is reached b = new byte[1024]; int total = 0; int len = 0; while ((len = in.read(b, total, b.length - total)) != -1) { total += len; if (total >= b.length) { byte[] tmp = new byte[total * 2]; System.arraycopy(b, 0, tmp, 0, total); b = tmp; } } // Trim array to correct size, if necessary if (total != b.length) { byte[] tmp = new byte[total]; System.arraycopy(b, 0, tmp, 0, total); b = tmp; } } catch (Exception exp) { throw (ClassNotFoundException) new ClassNotFoundException().initCause(exp); } return defineClass(name, b, 0, b.length); } } protected String findLibrary(String libname) { String name = System.mapLibraryName(libname); File library = new File(libraryPath, name); // LOGGER.fine("Library " + library.getAbsolutePath()); String f = library.getAbsolutePath();// NOI18N if (library.exists() && library.canRead()) { return library.getAbsolutePath(); } return super.findLibrary(libname); } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAView.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.datasupport.DataRemovedListener; import org.graalvm.visualvm.core.datasupport.Stateful; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.coredump.CoreDump; import java.beans.PropertyChangeEvent; import javax.swing.ImageIcon; import javax.swing.JPanel; import org.openide.util.Utilities; import org.graalvm.visualvm.tools.sa.SaModelFactory; import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.beans.PropertyChangeListener; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JLabel; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.util.WeakListeners; /** * * @author poonam */ public class SAView extends DataSourceView implements PropertyChangeListener, DataRemovedListener, ActionListener { private DataViewComponent dvc; DataSource dataSource; SAModelImpl saModel = null; private boolean isAttached = false; MasterViewSupport master; ThreadsView threadsView; OopInspectorView oopInspector; StackTraceViewer stackTraceViewer; CodeViewer codeviewer; FindPanel findPointer; FindPanel findInHeap; FindPanel findInCode; //Reusing an image from the sources: private static final String IMAGE_PATH = "org/graalvm/visualvm/modules/saplugin/resources/SA.png"; // NOI18N private String dsString = "Process"; private boolean doNotShowMessage = false; public static boolean isClosing = false; public SAView(DataSource ds) { super(ds, "SA Plugin", new ImageIcon(Utilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false); dataSource = ds; isAttached = false; ds.notifyWhenRemoved(this); ds.addPropertyChangeListener(Stateful.PROPERTY_STATE, WeakListeners.propertyChange(this, ds)); if (ds instanceof Application) { dsString = "Process"; } else if (ds instanceof CoreDump){ dsString = "CoreDump"; } } public DataViewComponent getDataViewComponent() { return dvc; } @Override protected void removed() { detachFromProcess(dataSource); dataSource = null; } public void propertyChange(PropertyChangeEvent evt) { dataRemoved(dataSource); } public void dataRemoved(DataSource ds) { this.dataSource = null; } public void actionPerformed(ActionEvent e) { throw new UnsupportedOperationException("Not supported yet."); } @Override protected DataViewComponent createComponent() { // attachToProcess(dataSource); master = new MasterViewSupport(dataSource); //Master view: DataViewComponent.MasterView masterView = new DataViewComponent.MasterView("SA Plugin", null, master); DataViewComponent.MasterViewConfiguration masterConfiguration = new DataViewComponent.MasterViewConfiguration(false); dvc = new DataViewComponent(masterView, masterConfiguration); //addDetailsViews(); if (saModel != null) saModel.setView(this); return dvc; } private void addDetailsViews() { Cursor cur = dvc.getCursor(); dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR)); //Add detail views to the component: threadsView = new ThreadsView("Java Threads", 10); stackTraceViewer = new StackTraceViewer("Java Stack Trace", 20); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration( "Java Threads / Java Stack Trace", true), DataViewComponent.TOP_LEFT); dvc.addDetailsView(threadsView.getDetailsView(), DataViewComponent.TOP_LEFT); dvc.addDetailsView(stackTraceViewer.getDetailsView(), DataViewComponent.TOP_LEFT); oopInspector = new OopInspectorView(saModel, "Oop Inspector", 10); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration( "Oop Inspector", true), DataViewComponent.TOP_RIGHT); dvc.addDetailsView(oopInspector.getDetailsView(), DataViewComponent.TOP_RIGHT); codeviewer = new CodeViewer("Code Viewer", 10); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration( "Code Viewer", true), DataViewComponent.BOTTOM_LEFT); dvc.addDetailsView(codeviewer.getDetailsView(), DataViewComponent.BOTTOM_LEFT); findPointer = new FindPanel("Find Pointer", 10, 1); findInHeap = new FindPanel("Find Value in Heap", 20, 2); findInCode = new FindPanel("Find Value in CodeCache", 30, 3); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration( "Find Panel", true), DataViewComponent.BOTTOM_RIGHT); dvc.addDetailsView(findPointer.getDetailsView(), DataViewComponent.BOTTOM_RIGHT); dvc.addDetailsView(findInHeap.getDetailsView(), DataViewComponent.BOTTOM_RIGHT); dvc.addDetailsView(findInCode.getDetailsView(), DataViewComponent.BOTTOM_RIGHT); dvc.hideDetailsArea(DataViewComponent.BOTTOM_LEFT); dvc.hideDetailsArea(DataViewComponent.BOTTOM_RIGHT); dvc.setCursor(cur); } public OopInspectorView getOopInspectorView() { return oopInspector; } public void updateOopInspectorView(Object oop) { Cursor cur = dvc.getCursor(); dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR)); oopInspector.refresh(oop); dvc.showDetailsArea(DataViewComponent.TOP_RIGHT); dvc.selectDetailsView(oopInspector.getDetailsView()); dvc.setCursor(cur); } public void updateStackTraceView(Object thread) { Cursor cur = dvc.getCursor(); dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR)); stackTraceViewer.refresh(thread); dvc.selectDetailsView(stackTraceViewer.getDetailsView()); dvc.showDetailsArea(DataViewComponent.TOP_LEFT); dvc.setCursor(cur); } public boolean attachToProcess(DataSource ds) { if (isAttached) { return true; } Cursor cur = dvc.getCursor(); dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR)); try { saModel = (SAModelImpl) SaModelFactory.getSAAgentFor(ds); isAttached = saModel.attach(); dvc.setCursor(cur); return isAttached; } catch (Exception e) { e.printStackTrace(); NotifyDescriptor nd = new NotifyDescriptor.Message(e.getCause().toString(), NotifyDescriptor.INFORMATION_MESSAGE); DialogDisplayer.getDefault().notify(nd); // System.out.println(e.getCause().toString()); // if (e.getCause().toString().contains("Windbg Error: AttachProcess failed!")) { detachFromProcess(ds); // } } dvc.setCursor(cur); return false; } public void detachFromProcess(DataSource ds) { try { saModel = (SAModelImpl) SaModelFactory.getSAAgentFor(ds); saModel.detach(); isAttached = false; } catch (Exception e) { e.printStackTrace(); } } public void refreshView(DataSource ds) { Cursor cur = dvc.getCursor(); dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR)); threadsView.refresh(); oopInspector.refresh(null); stackTraceViewer.refresh(null); codeviewer.refresh(); findPointer.refresh(); findInHeap.refresh(); findInCode.refresh(); dvc.showDetailsArea(DataViewComponent.TOP_LEFT); dvc.selectDetailsView(threadsView.getDetailsView()); dvc.hideDetailsArea(DataViewComponent.BOTTOM_LEFT); dvc.hideDetailsArea(DataViewComponent.BOTTOM_RIGHT); dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT); dvc.showDetailsArea(DataViewComponent.TOP_LEFT); dvc.setCursor(cur); } public void removeDetailsViews(DataSource ds) { threadsView.remove(); oopInspector.remove(); stackTraceViewer.remove(); codeviewer.remove(); findPointer.remove(); findInHeap.remove(); findInCode.remove(); dvc.hideDetailsArea(DataViewComponent.TOP_LEFT); dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT); dvc.hideDetailsArea(DataViewComponent.BOTTOM_LEFT); dvc.hideDetailsArea(DataViewComponent.BOTTOM_RIGHT); } // ----------Master View---------------------------- private class MasterViewSupport extends JPanel { private JButton attachButton; JLabel vmInformation; DataSource dataSource; boolean firstTimeShow = true; public MasterViewSupport(DataSource ds) { this.dataSource = ds; saModel = (SAModelImpl) SaModelFactory.getSAAgentFor(dataSource); initComponents(dataSource); if (dataSource instanceof Application) { addHierarchyListener(new HierarchyListener() { public void hierarchyChanged(HierarchyEvent e) { if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) { if (isShowing()) { /* if (!isAttached && (dataSource != null)) { if (attachToProcess(dataSource)) { if (firstTimeShow) { try { saModel.readData(); } catch (Exception ex) { ex.printStackTrace(); } addVMInfo(dataSource); addDetailsViews(); firstTimeShow = false; } } setAttachButtonText("Detach from process"); refreshView(dataSource); } */ } else {/* if (!dvc.isVisible()) return; Component parent = dvc.getParent(); Component top = null; while (parent != null) { top = parent; parent = top.getParent(); } if (!top.isShowing()) return; if (!top.isVisible()) return; if (isAttached && (dataSource != null) && (doNotShowMessage == false) ) { if (isClosing == false) { MessagePanel messagePanel = new MessagePanel(); DialogDescriptor dd = new DialogDescriptor(messagePanel, "Warning!"); Object result = DialogDisplayer.getDefault().notify(dd); if (result == NotifyDescriptor.OK_OPTION) { detachFromProcess(dataSource); removeDetailsViews(dataSource); setAttachButtonText("Attach to " + dsString); } } }*/ } } } }); } } public DataViewComponent.MasterView getMasterView() { return new DataViewComponent.MasterView("SAPlugin", null, this); // NOI18N } private void addVMInfo(final DataSource ds) { JLabel label = new JLabel(); String vminfo = null; vminfo = saModel.getVmVersion() + " " + saModel.getVmName() + " " + saModel.getVmInfo(); label.setText(vminfo); add(label); } private void initComponents(final DataSource ds) { setLayout(new BorderLayout()); setOpaque(false); String buttonLabel = null; if (isAttached) { buttonLabel = "Detach from " + dsString; } else { buttonLabel = "Attach to " + dsString; } attachButton = new JButton(new AbstractAction(buttonLabel) { public void actionPerformed(ActionEvent e) { if (ds == null) { return; } Cursor cur = dvc.getCursor(); dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR)); if (isAttached) { detachFromProcess(ds); // removeWarning(); removeDetailsViews(ds); setAttachButtonText("Attach to " + dsString); } else { if (attachToProcess(ds)) { if (firstTimeShow) { try { saModel.readData(); } catch (Exception ex) { ex.printStackTrace(); } addVMInfo(dataSource); addDetailsViews(); firstTimeShow = false; } refreshView(ds); if (isAttached && (ds instanceof Application) && (doNotShowMessage == false)) { if (isClosing == false) { MessagePanel messagePanel = new MessagePanel(); //DialogDescriptor dd = new DialogDescriptor(messagePanel, "SAPlugin Warning !"); NotifyDescriptor nd = new NotifyDescriptor.Message((Object) messagePanel, NotifyDescriptor.INFORMATION_MESSAGE) ; Object result = DialogDisplayer.getDefault().notify(nd); /*if (result == NotifyDescriptor.OK_OPTION) { detachFromProcess(dataSource); removeDetailsViews(dataSource); setAttachButtonText("Attach to " + dsString); } * */ } } setAttachButtonText("Detach from " + dsString); } } dvc.setCursor(cur); } }); attachButton.setEnabled(true); JPanel buttonsArea = new JPanel(new BorderLayout()); buttonsArea.setOpaque(false); JPanel buttonsContainer = new JPanel(new BorderLayout(3, 0)); buttonsContainer.setOpaque(false); buttonsContainer.setBorder(BorderFactory.createEmptyBorder(9, 5, 20, 10)); buttonsContainer.add(attachButton, BorderLayout.WEST); buttonsArea.add(buttonsContainer, BorderLayout.NORTH); add(buttonsArea, BorderLayout.EAST); } void setAttachButtonText(String s) { if (attachButton != null) { attachButton.setText(s); } } } //Details views private class ThreadsView extends JComponent { private JPanel threads; private String caption; private int position; private DataViewComponent.DetailsView detailsView; private Object saListener = null; private JavaThreadsPanel threadsPanel = null; public ThreadsView(String caption, int position) { this.caption = caption; this.position = position; detailsView = null; initComponents(); } public DataViewComponent.DetailsView getDetailsView() { if (detailsView == null) { detailsView = new DataViewComponent.DetailsView(caption, null, position, this, null); } return detailsView; } public void refresh() { this.removeAll(); threadsPanel = saModel.createJavaThreadsPanel(); if (threadsPanel != null) { saListener = saModel.getSAListener(); threadsPanel.setListener(saListener); threads = threadsPanel.getPanel(); add(threads, BorderLayout.CENTER); } } private void initComponents() { setLayout(new BorderLayout()); } public void remove() { // threadsPanel.removeListener(saListener); this.removeAll(); } } private class CodeViewer extends JComponent { private JPanel codeviewer; private String caption; private int position; private DataViewComponent.DetailsView detailsView; public CodeViewer(String caption, int position) { this.caption = caption; this.position = position; initComponents(); } public DataViewComponent.DetailsView getDetailsView() { if (detailsView == null) { detailsView = new DataViewComponent.DetailsView(caption, null, position, this, null); } return detailsView; } public void refresh() { this.removeAll(); try { codeviewer = saModel.createCodeViewerPanel().getPanel(); } catch (Throwable t) { NotifyDescriptor nd = new NotifyDescriptor.Message("Code Viewer is not yet implemented for this platform", NotifyDescriptor.INFORMATION_MESSAGE); DialogDisplayer.getDefault().notify(nd); dvc.removeDetailsView(detailsView); return; } add(codeviewer, BorderLayout.CENTER); } private void initComponents() { setLayout(new BorderLayout()); } public void remove() { this.removeAll(); } } private class FindPanel extends JComponent { private JPanel findPanel; private String caption; private int position; private int mode; public FindPanel(String caption, int position, int mode) { this.caption = caption; this.position = position; this.mode = mode; initComponents(); } public DataViewComponent.DetailsView getDetailsView() { return new DataViewComponent.DetailsView(caption, null, position, this, null); } public void refresh() { this.removeAll(); switch (mode) { case 1: findPanel = saModel.createFindPointerPanel().getPanel(); break; case 2: findPanel = saModel.createFindInHeapPanel().getPanel(); break; case 3: findPanel = saModel.createFindInCodeCachePanel().getPanel(); break; } add(findPanel, BorderLayout.CENTER); } private void initComponents() { setLayout(new BorderLayout()); } public void remove() { this.removeAll(); } } private class StackTraceViewer extends JComponent { private JPanel traceViewer; private String caption; private int position; private DataViewComponent.DetailsView detailsView; public StackTraceViewer(String caption, int position) { this.caption = caption; this.position = position; detailsView = null; initComponents(); } public DataViewComponent.DetailsView getDetailsView() { if (detailsView == null) { detailsView = new DataViewComponent.DetailsView(caption, null, position, this, null); } return detailsView; } public void refresh(Object thread) { this.removeAll(); try { JavaStackTracePanel tracePanel = saModel.createJavaStackTracePanel(); if (thread != null) { tracePanel.setJavaThread(thread); } traceViewer = tracePanel.getPanel(); } catch (Throwable t) { NotifyDescriptor nd = new NotifyDescriptor.Message("Java Stack Trace Viewer is not yet implemented for this platform", NotifyDescriptor.INFORMATION_MESSAGE); DialogDisplayer.getDefault().notify(nd); dvc.removeDetailsView(detailsView); return; } add(traceViewer, BorderLayout.CENTER); } private void initComponents() { setLayout(new BorderLayout()); } public void remove() { this.removeAll(); } } public class MessagePanel extends JPanel implements ItemListener { private String warning = new String("" + "
  Other tabs for this process will not be usable as long as
" + "  SAPlugin is attached to it. Please detach SAPlugin from
" + "  the process before using other tabs.

"); public MessagePanel() { initComponents(); } void initComponents() { setLayout(new BorderLayout()); //setSize(150,100); JLabel msg = new JLabel(warning); this.add(msg,BorderLayout.NORTH); JCheckBox check = new JCheckBox("Do not show this message again"); add(check, BorderLayout.SOUTH); check.addItemListener(this); } public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { doNotShowMessage = true; } } } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAViewProvider.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.snapshot.Snapshot; import org.graalvm.visualvm.core.ui.DataSourceView; import org.graalvm.visualvm.core.ui.DataSourceViewsManager; import org.graalvm.visualvm.core.ui.DataSourceViewProvider; import org.graalvm.visualvm.coredump.CoreDump; import org.graalvm.visualvm.host.Host; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory; import java.io.File; /** * * @author poonam */ class SAViewProvider extends DataSourceViewProvider { private static DataSourceViewProvider instance = new SAViewProvider(); private SAView saview = null; @Override public boolean supportsViewFor(DataSource ds) { if (ds == Application.CURRENT_APPLICATION) return false; if (ds instanceof Application) { if (Host.LOCALHOST.equals(((Application) ds).getHost())) { JvmJvmstatModel jvmstat = JvmJvmstatModelFactory.getJvmstatModelFor((Application) ds); if (jvmstat == null) { return false; } File jdkHome = new File(jvmstat.getJavaHome()); if ("jre".equals(jdkHome.getName())) { jdkHome = jdkHome.getParentFile(); } File saJar = SAModelProvider.getSaJar(jdkHome); if (saJar == null) { return false; } else { return true; } } } else if (ds instanceof CoreDump) { CoreDump coredump = (CoreDump) ds; File executable = new File(coredump.getExecutable()); File coreFile = coredump.getFile(); if (executable.exists() && coreFile.exists()) { File jdkHome = executable.getParentFile().getParentFile(); File saJar = SAModelProvider.getSaJar(jdkHome); if (saJar == null) { return false; } else { return true; } } } return false; } @Override public synchronized DataSourceView createView(final DataSource ds) { saview = new SAView(ds); return saview; } //@Override public boolean supportsSaveViewsFor(DataSource arg0) { return false; } // @Override public void saveViews(DataSource arg0, Snapshot arg1) { } void initialize() { DataSourceViewsManager.sharedInstance().addViewProvider(instance, DataSource.class); } static void unregister() { DataSourceViewsManager.sharedInstance().removeViewProvider(instance); } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAWrapper.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.logging.Logger; class SAWrapper { private static final Logger LOGGER = Logger.getLogger(SAWrapper.class.getName()); URLClassLoader loader; private static ClassLoader parent; File libraryPath; SAWrapper(File jdkHome, File saJarFile) throws MalformedURLException { // By default SA agent classes prefer dbx debugger to proc debugger // and Windows process debugger to windbg debugger. SA expects // special properties to be set to choose other debuggers. // We will set those here before attaching to SA agent. System.setProperty("sun.jvm.hotspot.debugger.useProcDebugger", "true"); // NOI18N System.setProperty("sun.jvm.hotspot.debugger.useWindbgDebugger", "true"); // NOI18N //File maf = new File(jdkHome, "lib/maf-1_0.jar"); URL[] saJarUrls = new URL[]{saJarFile.toURI().toURL()/*, maf.toURI().toURL()*/}; // String osArch = System.getProperty("os.arch"); // NOI18N // if ("x86".equals(osArch)) { // osArch = "i386"; // } //libraryPath = new File("lib/" + osArch); // NOI18N /// Changed this libraryPath = new File(jdkHome, "jre/bin/"); LOGGER.fine("Path " + libraryPath.getAbsolutePath()); // NOI18N //We want only one parent for all the SAPluginClassLoader instances. if (parent == null) parent = new URLClassLoader(new URL[]{saJarFile.toURI().toURL()}); loader = new SAPluginClassLoader(parent, jdkHome, saJarFile); /* loader = new URLClassLoader(saJarUrls, parent) { @Override protected String findLibrary(String libname) { String name = System.mapLibraryName(libname); File library = new File(libraryPath, name); LOGGER.fine("Library " + library.getAbsolutePath()); String f = library.getAbsolutePath();// NOI18N if (library.exists() && library.canRead()) { //return "D:/Java/jdk1.6.0_03/jre/lib/i386/sawindbg.dll"; return library.getAbsolutePath(); } return super.findLibrary(libname); } @Override public synchronized Class loadClass(String name) throws ClassNotFoundException { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { /* If we are loading any class in 'sun.jvm.hotspot.' or any of the * sub-packages (except for 'debugger' sub-pkg. please refer below), * we load it by 'this' loader. Or else, we forward the request to * 'parent' loader, system loader etc. (rest of the code follows * the patten in java.lang.ClassLoader.loadClass). * * 'sun.jvm.hotspot.debugger.' and sub-package classes are * also loaded by parent loader. This is done for two reasons: * * 1. to avoid code bloat by too many classes. * 2. to avoid loading same native library multiple times * from multiple class loaders (which results in getting a * UnsatisifiedLinkageError from System.loadLibrary). * if (name.startsWith("sun.jvm.hotspot.") && !name.startsWith("sun.jvm.hotspot.debugger.")) { return findClass(name); } if (name.startsWith("sun.jvm.hotspot.debugger.")) { c = parent.loadClass(name); } else if (parent != null) { c = parent.loadClass(name); } else { c = findSystemClass(name); } } return c; } }; } */ } Class classForName(String name) throws ClassNotFoundException { return Class.forName(name, true, loader); } Class Tool() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.tools.Tool"); // NOI18N } Class VM() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.runtime.VM"); // NOI18N } Class BugspotAgent() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.bugspot.BugSpotAgent"); // NOI18N } Class HotspotAgent() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.HotSpotAgent"); // NOI18N } Class HeapHprofBinWriter() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.utilities.HeapHprofBinWriter"); // NOI18N } Class Arguments() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.runtime.Arguments"); // NOI18N } /////////////////////////////////// Class OopInspector() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.ui.Inspector"); // NOI18N } Class JavaStackTracePanel() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.ui.JavaStackTracePanel"); // NOI18N } Class JavaThreadsPanel() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.ui.JavaThreadsPanel"); // NOI18N } Class SAListener() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.ui.SAListener"); // NOI18N } Class OopTreeNodeAdapter() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.ui.tree.OopTreeNodeAdapter"); // NOI18N } Class SimpleTreeNode() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.ui.tree.SimpleTreeNode"); // NOI18N } Class CodeViewerPanel() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.ui.classbrowser.CodeViewerPanel"); // NOI18N } Class FindPanel() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.ui.FindPanel"); // NOI18N } Class FindInHeapPanel() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.ui.FindInHeapPanel"); // NOI18N } Class FindInCodeCachePanel() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.ui.FindInCodeCachePanel"); // NOI18N } //Non-ui Class Oop() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.oops.Oop"); // NOI18N } Class JavaThread() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.runtime.JavaThread"); // NOI18N } Class FieldIdentifier() throws ClassNotFoundException { return classForName("sun.jvm.hotspot.oops.FieldIdentifier"); // NOI18N } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/StackTrace.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author Tomas Hurka */ class StackTrace { private VM vm; private SAObject heap; private SAObject objectClass; StackTrace(VM v) throws IllegalAccessException, InvocationTargetException { vm = v; heap = vm.getObjectHeap(); objectClass = vm.getSystemDictionary().invokeSA("getObjectKlass"); // NOI18N } public String getStackTrace() throws IllegalAccessException, InvocationTargetException { ByteArrayOutputStream data = new ByteArrayOutputStream(4096); PrintStream out = new PrintStream(data); SAObject threads = vm.getThreads(); SAObject curThread = threads.invokeSA("first"); // NOI18N for (;!curThread.isNull();curThread=curThread.invokeSA("next")) { // NOI18N try { Boolean isJavaThread = (Boolean) curThread.invoke("isJavaThread"); // NOI18N if (!isJavaThread.booleanValue()) { out.print("VM "); // NOI18N } out.print("Thread "); // NOI18N curThread.invoke("printThreadIDOn",out); // NOI18N out.print(" \""+curThread.invoke("getThreadName")+"\""); // NOI18N out.print(": (state = "); // NOI18N out.print(curThread.invoke("getThreadState")); // NOI18N out.println(")"); if (isJavaThread.booleanValue()) { // Java thread SAObject javaFrame = curThread.invokeSA("getLastJavaVFrameDbg"); // NOI18N Object waitingToLockMonitor = curThread.invoke("getCurrentPendingMonitor"); // NOI18N boolean objectWaitFrame = isJavaLangObjectWaitFrame(javaFrame); for (;!javaFrame.isNull();javaFrame=javaFrame.invokeSA("javaSender")) { // NOI18N printJavaFrame(out, javaFrame); printMonitors(out, javaFrame, waitingToLockMonitor, objectWaitFrame); waitingToLockMonitor = null; objectWaitFrame = false; } } } catch (Exception ex) { out.println("\t-- Error occurred during stack walking"); Logger.getLogger(StackTrace.class.getName()).log(Level.INFO,"getStackTrace",ex); } out.println(); } return data.toString(); } private boolean isJavaLangObjectWaitFrame(SAObject javaFrame) throws IllegalAccessException, InvocationTargetException { if (!javaFrame.isNull()) { SAObject method = javaFrame.invokeSA("getMethod"); // NOI18N SAObject klass = method.invokeSA("getMethodHolder"); // NOI18N Boolean isNative = (Boolean) method.invoke("isNative"); // NOI18N if (objectClass.equals(klass) && isNative.booleanValue()) { if ("wait".equals(method.invokeSA("getName").invoke("asString"))) { // NOI18N return true; } } } return false; } private void printMonitors( final PrintStream out, final SAObject javaFrame, Object waitingToLockMonitor, boolean objectWaitFrame) throws IllegalAccessException, InvocationTargetException { if (objectWaitFrame) { SAObject stackValueCollection = javaFrame.invokeSA("getLocals"); // NOI18N Boolean isEmpty = (Boolean) stackValueCollection.invoke("isEmpty"); // NOI18N if (!isEmpty.booleanValue()) { Object oopHandle = stackValueCollection.invoke("oopHandleAt", 0); // NOI18N printMonitor(out, oopHandle, "waiting on"); // NOI18N } } try { List mList = (List) javaFrame.invoke("getMonitors"); // NOI18N Object[] monitors = mList.toArray(); for (int i = monitors.length - 1; i >= 0; i--) { SAObject monitorInfo = new SAObject(monitors[i]); Object ownerHandle = monitorInfo.invoke("owner"); // NOI18N if (ownerHandle != null) { String state = "locked"; // NOI18N if (waitingToLockMonitor != null) { Object objectHandle = new SAObject(waitingToLockMonitor).invoke("object"); // NOI18N if (objectHandle.equals(ownerHandle)) { state = "waiting to lock"; // NOI18N } } printMonitor(out, ownerHandle, state); } } } catch (Exception e) { // Ignore... } } private void printMonitor( final PrintStream out, final Object ownerHandle, final String state) { try { StringBuilder sb = new StringBuilder(); sb.append("\t- " + state + " <" + ownerHandle + "> "); // NOI18N printOop(sb, ownerHandle); out.println(sb.toString()); } catch (Exception e) { // Ignore... } } private void printOop(StringBuilder sb, Object oopHandle) throws IllegalAccessException, InvocationTargetException { SAObject oop = heap.invokeSA("newOop", oopHandle); // NOI18N if (!oop.isNull()) { sb.append("(a "); // NOI18N String monitorClassName = (String) oop.invokeSA("getKlass").invokeSA("getName").invoke("asString"); // NOI18N sb.append(monitorClassName.replace('/', '.')); sb.append(")"); } else { sb.append("(Raw Monitor)"); // NOI18N } } private void printJavaFrame(final PrintStream out, final SAObject javaFrame) throws IllegalAccessException, InvocationTargetException { SAObject method = javaFrame.invokeSA("getMethod"); // NOI18N out.print("\tat "); // NOI18N SAObject klass = method.invokeSA("getMethodHolder"); // NOI18N String className = (String) klass.invokeSA("getName").invoke("asString"); // NOI18N out.print(className.replace('/','.')); out.print("."); out.print(method.invokeSA("getName").invoke("asString")); // NOI18N Integer bci = (Integer) javaFrame.invoke("getBCI"); // NOI18N out.print("("); if (((Boolean)method.invoke("isNative")).booleanValue()) { // NOI18N out.print("Native Method"); // NOI18N } else { Integer lineNumber = (Integer) method.invoke("getLineNumberFromBCI",bci); // NOI18N SAObject sourceName = klass.invokeSA("getSourceFileName"); // NOI18N if (lineNumber.intValue()!=-1 && !sourceName.isNull()) { out.print(sourceName.invoke("asString")); // NOI18N out.print(":"); out.print(lineNumber); } else { out.print("bci="); // NOI18N out.print(bci); } } out.println(")"); } } ================================================ FILE: plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/VM.java ================================================ /* * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.saplugin; import java.lang.reflect.InvocationTargetException; import java.util.Properties; /** * * @author Tomas Hurka */ class VM { private final SAObject vm; VM(Object saVM) { vm = new SAObject(saVM); } Properties getSystemProperties() throws IllegalAccessException, InvocationTargetException { return (Properties) vm.invoke("getSystemProperties"); // NOI18N } SAObject getThreads() throws IllegalAccessException, InvocationTargetException { return vm.invokeSA("getThreads"); // NOI18N } SAObject getObjectHeap() throws IllegalAccessException, InvocationTargetException { return vm.invokeSA("getObjectHeap"); // NOI18N } SAObject getSystemDictionary() throws IllegalAccessException, InvocationTargetException { return vm.invokeSA("getSystemDictionary"); // NOI18N } } ================================================ FILE: plugins/security/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.security. ================================================ FILE: plugins/security/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.modules.security/2 OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/security/Bundle.properties OpenIDE-Module-Install: org/graalvm/visualvm/modules/security/Installer.class OpenIDE-Module-Specification-Version: 2.0 ================================================ FILE: plugins/security/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/security/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=00c4bee7 build.xml.script.CRC32=c28e99b3 build.xml.stylesheet.CRC32=a56c6a5b@2.73 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=00c4bee7 nbproject/build-impl.xml.script.CRC32=1b990c4b nbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73 ================================================ FILE: plugins/security/nbproject/project.properties ================================================ javac.source=1.5 javac.compilerargs=-Xlint -Xlint:-serial license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Jiri Sedlacek module.javadoc.packages=org.graalvm.visualvm.modules.security.* ================================================ FILE: plugins/security/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.security org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.uisupport 2 2.0 org.netbeans.modules.options.api 1 1.5.1 org.openide.awt 6.11.1.1 org.openide.dialogs 7.5.1 org.openide.modules 7.3 org.openide.util 9.8 org.openide.util.lookup 8.3.1 org.openide.util.ui 9.8 org.openide.windows 6.18.1 ================================================ FILE: plugins/security/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/security/src/org/graalvm/visualvm/modules/security/Bundle.properties ================================================ OpenIDE-Module-Display-Category=Security OpenIDE-Module-Long-Description=\ This plugin provides a GUI for setting the standard system properties controlling SSL/TLS connections in VisualVM. \ Setting the properties using the plugin is equivalent to providing the properties on the command line. \ However, the properties provided on the command line take precedence and if set the GUI editing is disabled.\n\
\n
\nCurrently the plugin supports editing these system properties:\n
\n
    \n
  • javax.net.ssl.keyStore
  • \n
  • javax.net.ssl.keyStoreType
  • \n
  • javax.net.ssl.keyStorePassword
  • \n
  • javax.net.ssl.trustStore
  • \n
  • javax.net.ssl.trustStoreType
  • \n
  • javax.net.ssl.trustStorePassword
  • \n
  • javax.rmi.ssl.client.enabledCipherSuites
  • \n
  • javax.rmi.ssl.client.enabledProtocols
  • \n
OpenIDE-Module-Name=VisualVM-Security OpenIDE-Module-Short-Description=Options category for customizing SSL certificates, protocols and cipher suites OptionsCategory_Name_Security=Security MSG_SaveToFile=Save Security Settings To File MSG_FailedSaveToFile=Failed to save security settings MSG_LoadFromFile=Load Security Settings From File MSG_FailedLoadFromFile=Failed to load security settings CAP_SelectProtocols=Select Protocols To Enable HINT_SelectProtocols=Select the &protocols to enable\: COL_Protocols=Protocols CAP_SelectCipherSuites=Select Cipher Suites To Enable HINT_SelectCipherSuites=Select the &cipher suites to enable\: COL_CipherSuites=Cipher Suites COL_Enabled=Enabled ACT_SelectAll=&Select All ACT_DeselectAll=&Deselect All MSG_AlreadyDefined=Properties already defined using the command line options on VisualVM startup. Remove the command line options to enable the GUI settings. SEP_Certificates=Certificates CHK_KeyStore=&Key store\: MSG_ValueOf=Value of {0} BTN_Browse1=&Browse... CAP_SelectKeyStore=Select Key Store File LBL_Password1=P&assword\: LBL_Type1=T&ype\: OPT_Default=Default CHK_TrustStore=&Trust store\: BTN_Browse2=B&rowse... CAP_SelectTrustStore=Select Trust Store File LBL_Password2=Pass&word\: LBL_Type2=Typ&e\: SEP_Protocols=Protocols CHK_Protocols=&Protocols\: BTN_Customize1=C&ustomize... CHK_CipherSuites=&Cipher suites\: BTN_Customize2=Cust&omize... SEP_ExportImport=Export / Import BTN_LoadFromFile=&Load From File... BTN_SaveToFile=&Save To File... MSG_RestartVisualVM=VisualVM needs to be restarted for the changes to take effect. CHK_RestartVisualVM=Restart &VisualVM after clicking the OK button ================================================ FILE: plugins/security/src/org/graalvm/visualvm/modules/security/Installer.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.security; import java.util.logging.Level; import java.util.logging.Logger; import org.openide.modules.ModuleInstall; /** * * @author Jiri Sedlacek */ public class Installer extends ModuleInstall { private static final Logger LOGGER = Logger.getLogger(Installer.class.getName()); public void restored() { SecurityModel model = SecurityModel.getInstance(); if (!model.environmentCustomized()) { if (model.customizeEnvironment()) LOGGER.log(Level.INFO, "VisualVM-Security customized security environment"); // NOI18N } else { LOGGER.log(Level.INFO, "VisualVM-Security detected customized security environment"); // NOI18N } } } ================================================ FILE: plugins/security/src/org/graalvm/visualvm/modules/security/PersistenceSupport.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.security; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JFileChooser; import javax.swing.SwingUtilities; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; import org.openide.windows.WindowManager; /** * * @author Jiri Sedlacek */ class PersistenceSupport { private static final String SNAPSHOT_VERSION = "snapshot_version"; // NOI18N private static final String SNAPSHOT_VERSION_DIVIDER = "."; private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = "1"; // NOI18N private static final String CURRENT_SNAPSHOT_VERSION_MINOR = "0"; // NOI18N private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR; private static final Logger LOGGER = Logger.getLogger(PersistenceSupport.class.getName()); static File chooseLoadFile(String title, File startFile) { JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle(title); chooser.setSelectedFile(startFile); if (chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) return chooser.getSelectedFile(); return null; } static File chooseSaveFile(String title) { JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle(title); if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) return chooser.getSelectedFile(); return null; } static void saveToFile(SecurityOptionsPanel panel) { final File file = chooseSaveFile(NbBundle.getMessage( PersistenceSupport.class, "MSG_SaveToFile")); // NOI18N if (file == null) return; final Properties props = new Properties(); props.put(SNAPSHOT_VERSION, CURRENT_SNAPSHOT_VERSION); String keyStore = panel.getKeyStore(); if (keyStore != null) { props.put(SecurityModel.KEYSTORE_LOCATION, keyStore); char[] keyStorePassword = panel.getKeyStorePassword(); if (keyStorePassword != null) props.put(SecurityModel.KEYSTORE_PASSWORD, new String(keyStorePassword)); String keyStoreType = panel.getKeyStoreType(); if (keyStoreType != null) props.put(SecurityModel.KEYSTORE_TYPE, keyStoreType); } String trustStore = panel.getTrustStore(); if (trustStore != null) { props.put(SecurityModel.TRUSTSTORE_LOCATION, trustStore); char[] trustStorePassword = panel.getTrustStorePassword(); if (trustStorePassword != null) props.put(SecurityModel.TRUSTSTORE_PASSWORD, new String(trustStorePassword)); String trustStoreType = panel.getTrustStoreType(); if (trustStoreType != null) props.put(SecurityModel.TRUSTSTORE_TYPE, trustStoreType); } String enabledProtocols = panel.getEnabledProtocols(); if (enabledProtocols != null) props.put(SecurityModel.ENABLED_PROTOCOLS, enabledProtocols); String enabledCipherSuites = panel.getEnabledCipherSuites(); if (enabledCipherSuites != null) props.put(SecurityModel.ENABLED_CIPHER_SUITES, enabledCipherSuites); RequestProcessor.getDefault().post(new Runnable() { public void run() { boolean saved = saveProperties(props, file); if (!saved) { NotifyDescriptor nd = new NotifyDescriptor.Message( NbBundle.getMessage(PersistenceSupport.class, "MSG_FailedSaveToFile"), NotifyDescriptor.ERROR_MESSAGE); // NOI18N DialogDisplayer.getDefault().notifyLater(nd); return; } } }); } static void loadFromFile(final SecurityOptionsPanel panel) { final File file = chooseLoadFile(NbBundle.getMessage(PersistenceSupport.class, "MSG_LoadFromFile"), null); // NOI18N if (file == null) return; RequestProcessor.getDefault().post(new Runnable() { public void run() { final Properties props = loadProperties(file); if (props == null) { NotifyDescriptor nd = new NotifyDescriptor.Message( NbBundle.getMessage(PersistenceSupport.class, "MSG_FailedLoadFromFile"), NotifyDescriptor.ERROR_MESSAGE); DialogDisplayer.getDefault().notifyLater(nd); return; } SwingUtilities.invokeLater(new Runnable() { public void run() { panel.setKeyStore(props.getProperty(SecurityModel.KEYSTORE_LOCATION)); String keyStorePassword = props.getProperty(SecurityModel.KEYSTORE_PASSWORD); panel.setKeyStorePassword(keyStorePassword == null ? null : keyStorePassword.toCharArray()); panel.setKeyStoreType(props.getProperty(SecurityModel.KEYSTORE_TYPE)); panel.setTrustStore(props.getProperty(SecurityModel.TRUSTSTORE_LOCATION)); String trustStorePassword = props.getProperty(SecurityModel.TRUSTSTORE_PASSWORD); panel.setTrustStorePassword(trustStorePassword == null ? null : trustStorePassword.toCharArray()); panel.setTrustStoreType(props.getProperty(SecurityModel.TRUSTSTORE_TYPE)); panel.setEnabledProtocols(props.getProperty(SecurityModel.ENABLED_PROTOCOLS)); panel.setEnabledCipherSuites(props.getProperty(SecurityModel.ENABLED_CIPHER_SUITES)); } }); } }); } private static boolean saveProperties(Properties properties, File file) { OutputStream os = null; BufferedOutputStream bos = null; try { os = new FileOutputStream(file); bos = new BufferedOutputStream(os); properties.storeToXML(os, null); return true; } catch (Exception e) { LOGGER.log(Level.INFO, "Error storing properties to " + file, e); // NOI18N return false; } finally { try { if (bos != null) bos.close(); if (os != null) os.close(); } catch (Exception e) { LOGGER.log(Level.INFO, "Problem closing output stream", e); // NOI18N } } } private static Properties loadProperties(File file) { InputStream is = null; BufferedInputStream bis = null; try { is = new FileInputStream(file); bis = new BufferedInputStream(is); Properties properties = new Properties(); properties.loadFromXML(bis); return properties; } catch (Exception e) { LOGGER.log(Level.INFO, "Error loading properties from " + file, e); // NOI18N return null; } finally { try { if (bis != null) bis.close(); if (is != null) is.close(); } catch (Exception e) { LOGGER.log(Level.INFO, "Problem closing input stream", e); // NOI18N } } } } ================================================ FILE: plugins/security/src/org/graalvm/visualvm/modules/security/SecurityModel.java ================================================ /* * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.security; import java.util.prefs.Preferences; import org.graalvm.visualvm.core.datasupport.Utils; import org.openide.util.NbPreferences; /** * * @author Jiri Sedlacek */ class SecurityModel { static final String KEYSTORE_LOCATION = "javax.net.ssl.keyStore"; // NOI18N static final String KEYSTORE_TYPE = "javax.net.ssl.keyStoreType"; // NOI18N static final String KEYSTORE_PASSWORD = "javax.net.ssl.keyStorePassword"; // NOI18N static final String TRUSTSTORE_LOCATION = "javax.net.ssl.trustStore"; // NOI18N static final String TRUSTSTORE_TYPE = "javax.net.ssl.trustStoreType"; // NOI18N static final String TRUSTSTORE_PASSWORD = "javax.net.ssl.trustStorePassword"; // NOI18N static final String ENABLED_CIPHER_SUITES = "javax.rmi.ssl.client.enabledCipherSuites"; // NOI18N static final String ENABLED_PROTOCOLS = "javax.rmi.ssl.client.enabledProtocols"; // NOI18N private static final String CUSTOMIZED_MSG = "Environment already customized by command line"; // NOI18N private static SecurityModel INSTANCE; private final boolean environmentCustomized; private final Preferences prefs; static synchronized SecurityModel getInstance() { if (INSTANCE == null) INSTANCE = new SecurityModel(); return INSTANCE; } boolean environmentCustomized() { return environmentCustomized; } boolean customizeEnvironment() { if (environmentCustomized) throw new UnsupportedOperationException(CUSTOMIZED_MSG); boolean customized = false; String keyStore = getKeyStore(); if (keyStore != null) { customized = true; System.setProperty(KEYSTORE_LOCATION, keyStore); char[] keyStorePassword = getKeyStorePassword(); if (keyStorePassword != null) System.setProperty(KEYSTORE_PASSWORD, new String(keyStorePassword)); String keyStoreType = getKeyStoreType(); if (keyStoreType != null) System.setProperty(KEYSTORE_TYPE, keyStoreType); } String trustStore = getTrustStore(); if (trustStore != null) { customized = true; System.setProperty(TRUSTSTORE_LOCATION, trustStore); char[] trustStorePassword = getTrustStorePassword(); if (trustStorePassword != null) System.setProperty(TRUSTSTORE_PASSWORD, new String(trustStorePassword)); String trustStoreType = getTrustStoreType(); if (trustStoreType != null) System.setProperty(TRUSTSTORE_TYPE, trustStoreType); } String enabledProtocols = getEnabledProtocols(); if (enabledProtocols != null) { customized = true; System.setProperty(ENABLED_PROTOCOLS, enabledProtocols); } String enabledCipherSuites = getEnabledCipherSuites(); if (enabledCipherSuites != null) { customized = true; System.setProperty(ENABLED_CIPHER_SUITES, enabledCipherSuites); } return customized; } String getKeyStore() { if (environmentCustomized) return getKeyStoreEnv(); else return prefs.get(KEYSTORE_LOCATION, null); } static String getKeyStoreEnv() { return System.getProperty(KEYSTORE_LOCATION); } void setKeyStore(String keyStore) { if (environmentCustomized) throw new UnsupportedOperationException(CUSTOMIZED_MSG); if (keyStore == null) prefs.remove(KEYSTORE_LOCATION); else prefs.put(KEYSTORE_LOCATION, keyStore); } char[] getKeyStorePassword() { if (environmentCustomized) return getKeyStorePasswordEnv(); String password = prefs.get(KEYSTORE_PASSWORD, null); return password == null ? null : Utils.decodePassword(password).toCharArray(); } static char[] getKeyStorePasswordEnv() { String password = System.getProperty(KEYSTORE_PASSWORD); return password == null ? null : password.toCharArray(); } void setKeyStorePassword(char[] keyStorePassword) { if (environmentCustomized) throw new UnsupportedOperationException(CUSTOMIZED_MSG); if (keyStorePassword == null) prefs.remove(KEYSTORE_PASSWORD); else prefs.put(KEYSTORE_PASSWORD, Utils.encodePassword( new String(keyStorePassword))); } String getKeyStoreType() { if (environmentCustomized) return getKeyStoreTypeEnv(); else return prefs.get(KEYSTORE_TYPE, null); } static String getKeyStoreTypeEnv() { return System.getProperty(KEYSTORE_TYPE); } void setKeyStoreType(String keyStoreType) { if (environmentCustomized) throw new UnsupportedOperationException(CUSTOMIZED_MSG); if (keyStoreType == null) prefs.remove(KEYSTORE_TYPE); else prefs.put(KEYSTORE_TYPE, keyStoreType); } String getTrustStore() { if (environmentCustomized) return getTrustStoreEnv(); else return prefs.get(TRUSTSTORE_LOCATION, null); } static String getTrustStoreEnv() { return System.getProperty(TRUSTSTORE_LOCATION); } void setTrustStore(String trustStore) { if (environmentCustomized) throw new UnsupportedOperationException(CUSTOMIZED_MSG); if (trustStore == null) prefs.remove(TRUSTSTORE_LOCATION); else prefs.put(TRUSTSTORE_LOCATION, trustStore); } char[] getTrustStorePassword() { if (environmentCustomized) return getTrustStorePasswordEnv(); String password = prefs.get(TRUSTSTORE_PASSWORD, null); return password == null ? null : Utils.decodePassword(password).toCharArray(); } static char[] getTrustStorePasswordEnv() { String password = System.getProperty(TRUSTSTORE_PASSWORD); return password == null ? null : password.toCharArray(); } void setTrustStorePassword(char[] trustStorePassword) { if (environmentCustomized) throw new UnsupportedOperationException(CUSTOMIZED_MSG); if (trustStorePassword == null) prefs.remove(TRUSTSTORE_PASSWORD); else prefs.put(TRUSTSTORE_PASSWORD, Utils.encodePassword( new String(trustStorePassword))); } String getTrustStoreType() { if (environmentCustomized) return getTrustStoreTypeEnv(); else return prefs.get(TRUSTSTORE_TYPE, null); } static String getTrustStoreTypeEnv() { return System.getProperty(TRUSTSTORE_TYPE); } void setTrustStoreType(String trustStoreType) { if (environmentCustomized) throw new UnsupportedOperationException(CUSTOMIZED_MSG); if (trustStoreType == null) prefs.remove(TRUSTSTORE_TYPE); else prefs.put(TRUSTSTORE_TYPE, trustStoreType); } String getEnabledProtocols() { if (environmentCustomized) return getEnabledProtocolsEnv(); else return prefs.get(ENABLED_PROTOCOLS, null); } static String getEnabledProtocolsEnv() { return System.getProperty(ENABLED_PROTOCOLS); } void setEnabledProtocols(String enabledProtocols) { if (environmentCustomized) throw new UnsupportedOperationException(CUSTOMIZED_MSG); if (enabledProtocols == null) prefs.remove(ENABLED_PROTOCOLS); // NOI18N else prefs.put(ENABLED_PROTOCOLS, enabledProtocols); } String getEnabledCipherSuites() { if (environmentCustomized) return getEnabledCipherSuitesEnv(); else return prefs.get(ENABLED_CIPHER_SUITES, null); } static String getEnabledCipherSuitesEnv() { return System.getProperty(ENABLED_CIPHER_SUITES); } void setEnabledCipherSuites(String enabledCipherSuites) { if (environmentCustomized) throw new UnsupportedOperationException(CUSTOMIZED_MSG); if (enabledCipherSuites == null) prefs.remove(ENABLED_CIPHER_SUITES); // NOI18N else prefs.put(ENABLED_CIPHER_SUITES, enabledCipherSuites); } private static boolean environmentCustomizedImpl() { if (getKeyStoreEnv() != null) return true; else if (getKeyStorePasswordEnv() != null) return true; else if (getKeyStoreTypeEnv() != null) return true; else if (getTrustStoreEnv() != null) return true; else if (getTrustStorePasswordEnv() != null) return true; else if (getTrustStoreTypeEnv() != null) return true; else if (getEnabledProtocolsEnv() != null) return true; else if (getEnabledCipherSuitesEnv() != null) return true; return false; } private SecurityModel() { environmentCustomized = environmentCustomizedImpl(); prefs = NbPreferences.forModule(SecurityModel.class); } } ================================================ FILE: plugins/security/src/org/graalvm/visualvm/modules/security/SecurityOptionsPanel.java ================================================ /* * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.security; import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.File; import java.util.Arrays; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.graalvm.visualvm.core.options.UISupport; import org.graalvm.visualvm.core.ui.components.SectionSeparator; import org.graalvm.visualvm.core.ui.components.Spacer; import org.openide.awt.Mnemonics; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; /** * * @author Jiri Sedlacek */ class SecurityOptionsPanel extends JPanel { private static final String PASSWORD_NOT_CHANGED = "----------"; // NOI18N private final SecurityOptionsPanelController controller; private boolean dataValid; private char[] keyStorePassword; private char[] trustStorePassword; SecurityOptionsPanel(SecurityOptionsPanelController controller) { this.controller = controller; initComponents(); update(); } void cleanup() { setKeyStorePassword(PASSWORD_NOT_CHANGED.toCharArray()); setTrustStorePassword(PASSWORD_NOT_CHANGED.toCharArray()); } boolean dataValid() { return dataValid; } boolean shouldRestart() { return restartCheckBox.isSelected(); } void resetRestart() { restartCheckBox.setSelected(false); } String getKeyStore() { if (!keyStoreLocCheckBox.isSelected()) return null; return keyStoreLocField.getText().trim(); } void setKeyStore(String keyStore) { keyStoreLocCheckBox.setSelected(keyStore != null); if (keyStore != null) keyStoreLocField.setText(keyStore); else keyStoreLocField.setText(""); // NOI18N } char[] getKeyStorePassword() { if (!keyStoreLocCheckBox.isSelected()) return null; char[] password = keyStorePassField.getPassword(); if (Arrays.equals(password, PASSWORD_NOT_CHANGED.toCharArray())) return keyStorePassword; else return password; } void setKeyStorePassword(char[] keyStorePassword) { this.keyStorePassword = keyStorePassword; keyStorePassField.setText(PASSWORD_NOT_CHANGED); } String getKeyStoreType() { if (!keyStoreLocCheckBox.isSelected()) return null; if (keyStoreTypeCombo.getSelectedIndex() == 0) return null; return keyStoreTypeCombo.getSelectedItem().toString().trim(); } void setKeyStoreType(String keyStoreType) { if (keyStoreType == null) keyStoreTypeCombo.setSelectedIndex(0); else keyStoreTypeCombo.setSelectedItem(keyStoreType); } String getTrustStore() { if (!trustStoreLocCheckBox.isSelected()) return null; return trustStoreLocField.getText().trim(); } void setTrustStore(String trustStore) { trustStoreLocCheckBox.setSelected(trustStore != null); if (trustStore != null) trustStoreLocField.setText(trustStore); else trustStoreLocField.setText(""); // NOI18N } char[] getTrustStorePassword() { if (!trustStoreLocCheckBox.isSelected()) return null; char[] password = trustStorePassField.getPassword(); if (Arrays.equals(password, PASSWORD_NOT_CHANGED.toCharArray())) return trustStorePassword; else return password; } void setTrustStorePassword(char[] trustStorePassword) { this.trustStorePassword = trustStorePassword; trustStorePassField.setText(PASSWORD_NOT_CHANGED); } String getTrustStoreType() { if (!trustStoreLocCheckBox.isSelected()) return null; if (trustStoreTypeCombo.getSelectedIndex() == 0) return null; return trustStoreTypeCombo.getSelectedItem().toString().trim(); } void setTrustStoreType(String trustStoreType) { if (trustStoreType == null) trustStoreTypeCombo.setSelectedIndex(0); else trustStoreTypeCombo.setSelectedItem(trustStoreType); } String getEnabledProtocols() { if (!protocolsCheckBox.isSelected()) return null; return protocolsField.getText().trim(); } void setEnabledProtocols(String enabledProtocols) { protocolsCheckBox.setSelected(enabledProtocols != null); if (enabledProtocols != null) protocolsField.setText(enabledProtocols); else protocolsField.setText(""); // NOI18N } String getEnabledCipherSuites() { if (!cipherSuitesCheckBox.isSelected()) return null; return cipherSuitesField.getText().trim(); } void setEnabledCipherSuites(String enabledCipherSuites) { cipherSuitesCheckBox.setSelected(enabledCipherSuites != null); if (enabledCipherSuites != null) cipherSuitesField.setText(enabledCipherSuites); else cipherSuitesField.setText(""); // NOI18N } private void update() { SecurityModel model = controller.getModel(); boolean externallyCustomized = model.environmentCustomized(); boolean keyStoreCustomized = keyStoreLocCheckBox.isSelected(); keyStoreLocCheckBox.setEnabled(!externallyCustomized); keyStoreLocField.setEnabled(!externallyCustomized && keyStoreCustomized); keyStoreLocButton.setEnabled(!externallyCustomized && keyStoreCustomized); keyStorePassLabel.setEnabled(!externallyCustomized && keyStoreCustomized); keyStorePassField.setEnabled(!externallyCustomized && keyStoreCustomized); keyStoreTypeLabel.setEnabled(!externallyCustomized && keyStoreCustomized); keyStoreTypeCombo.setEnabled(!externallyCustomized && keyStoreCustomized); boolean keyStoreValid = !keyStoreCustomized || new File(keyStoreLocField.getText().trim()).isFile(); boolean trustStoreCustomized = trustStoreLocCheckBox.isSelected(); trustStoreLocCheckBox.setEnabled(!externallyCustomized); trustStoreLocField.setEnabled(!externallyCustomized && trustStoreCustomized); trustStoreLocButton.setEnabled(!externallyCustomized && trustStoreCustomized); trustStorePassLabel.setEnabled(!externallyCustomized && trustStoreCustomized); trustStorePassField.setEnabled(!externallyCustomized && trustStoreCustomized); trustStoreTypeLabel.setEnabled(!externallyCustomized && trustStoreCustomized); trustStoreTypeCombo.setEnabled(!externallyCustomized && trustStoreCustomized); boolean trustStoreValid = !trustStoreCustomized || new File(trustStoreLocField.getText().trim()).isFile(); boolean protocolsCustomized = protocolsCheckBox.isSelected(); protocolsCheckBox.setEnabled(!externallyCustomized); protocolsField.setEnabled(!externallyCustomized && protocolsCustomized); protocolsButton.setEnabled(!externallyCustomized && protocolsCustomized); boolean cipherSuitesCustomized = cipherSuitesCheckBox.isSelected(); cipherSuitesCheckBox.setEnabled(!externallyCustomized); cipherSuitesField.setEnabled(!externallyCustomized && cipherSuitesCustomized); cipherSuitesButton.setEnabled(!externallyCustomized && cipherSuitesCustomized); loadFromFileButton.setEnabled(!externallyCustomized); saveToFileButton.setEnabled(keyStoreCustomized || trustStoreCustomized || protocolsCustomized || cipherSuitesCustomized); dataValid = keyStoreValid && trustStoreValid; controller.changed(); SwingUtilities.invokeLater(new Runnable() { public void run() { hintPanel.setVisible(controller.differsFromEnv()); } }); } private void initComponents() { setLayout(new GridBagLayout()); GridBagConstraints c; // --- Notification header --------------------------------------------- // notificationLabel notificationArea = new JTextArea(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_AlreadyDefined")); // NOI18N notificationArea.setEditable(false); notificationArea.setEnabled(false); notificationArea.setLineWrap(true); notificationArea.setWrapStyleWord(true); notificationArea.setOpaque(false); notificationArea.setDisabledTextColor(notificationArea.getForeground()); notificationArea.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(Color.RED), BorderFactory.createEmptyBorder(5, 5, 5, 5))); notificationArea.setVisible(controller.getModel().environmentCustomized()); c = new GridBagConstraints(); c.gridy = 0; c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(0, 0, 15, 0); add(notificationArea, c); // --- KeyStore -------------------------------------------------------- // keyStoreSeparator SectionSeparator keyStoreSeparator = UISupport.createSectionSeparator( NbBundle.getMessage(SecurityOptionsPanel.class, "SEP_Certificates")); // NOI18N c = new GridBagConstraints(); c.gridy = 1; c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(0, 0, 0, 0); add(keyStoreSeparator, c); // keyStoreLocCheckBox keyStoreLocCheckBox = new JCheckBox(); Mnemonics.setLocalizedText(keyStoreLocCheckBox, NbBundle.getMessage( SecurityOptionsPanel.class, "CHK_KeyStore")); // NOI18N keyStoreLocCheckBox.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.KEYSTORE_LOCATION)); // NOI18N keyStoreLocCheckBox.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { update(); } }); c = new GridBagConstraints(); c.gridx = 0; c.gridy = 2; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(7, 10, 0, 0); add(keyStoreLocCheckBox, c); // keyStoreField keyStoreLocField = new JTextField(); keyStoreLocField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.KEYSTORE_LOCATION)); // NOI18N keyStoreLocField.setPreferredSize( new Dimension(250, keyStoreLocField.getPreferredSize().height)); keyStoreLocField.getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { update(); } public void removeUpdate(DocumentEvent e) { update(); } public void changedUpdate(DocumentEvent e) { update(); } }); c = new GridBagConstraints(); c.gridx = 1; c.gridy = 2; c.gridwidth = 1; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(7, 5, 0, 0); add(keyStoreLocField, c); // keyStoreLocButton keyStoreLocButton = new JButton(); Mnemonics.setLocalizedText(keyStoreLocButton, NbBundle.getMessage(SecurityOptionsPanel.class, "BTN_Browse1")); // NOI18N keyStoreLocButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { File currentFile = new File(keyStoreLocField.getText().trim()); File file = PersistenceSupport.chooseLoadFile( NbBundle.getMessage(SecurityOptionsPanel.class, "CAP_SelectKeyStore"), currentFile); // NOI18N if (file != null) keyStoreLocField.setText(file.toString()); } }); c = new GridBagConstraints(); c.gridx = 2; c.gridy = 2; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(7, 5, 0, 0); add(keyStoreLocButton, c); // keyStoreSettingsPanel JPanel keyStoreSettingsPanel = new JPanel(new GridBagLayout()); // keyStorePassLabel keyStorePassLabel = new JLabel(); Mnemonics.setLocalizedText(keyStorePassLabel, NbBundle.getMessage( SecurityOptionsPanel.class, "LBL_Password1")); // NOI18N keyStorePassLabel.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.KEYSTORE_PASSWORD)); // NOI18N c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 5, 0, 0); keyStoreSettingsPanel.add(keyStorePassLabel, c); // keyStorePassField keyStorePassField = new JPasswordField(); keyStorePassLabel.setLabelFor(keyStorePassField); keyStorePassField.getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { update(); } public void removeUpdate(DocumentEvent e) { update(); } public void changedUpdate(DocumentEvent e) { update(); } }); keyStorePassField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.KEYSTORE_PASSWORD)); // NOI18N c = new GridBagConstraints(); c.gridx = 1; c.gridy = 0; c.gridwidth = 1; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 5, 0, 0); keyStoreSettingsPanel.add(keyStorePassField, c); // keyStoreTypeLabel keyStoreTypeLabel = new JLabel(); Mnemonics.setLocalizedText(keyStoreTypeLabel, NbBundle.getMessage( SecurityOptionsPanel.class, "LBL_Type1")); // NOI18N keyStoreTypeLabel.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.KEYSTORE_TYPE)); // NOI18N c = new GridBagConstraints(); c.gridx = 2; c.gridy = 0; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; c.insets = new Insets(0, 25, 0, 0); keyStoreSettingsPanel.add(keyStoreTypeLabel, c); // keyStoreTypeCombo keyStoreTypeCombo = new JComboBox(new String[] { NbBundle.getMessage( SecurityOptionsPanel.class, "OPT_Default"), "jks", "pkcs12", "jceks" }) { // NOI18N public Dimension getMinimumSize() { return getPreferredSize(); } }; keyStoreTypeLabel.setLabelFor(keyStoreTypeCombo); keyStoreTypeCombo.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { update(); } }); keyStoreTypeCombo.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.KEYSTORE_TYPE)); // NOI18N keyStoreTypeCombo.setEditable(true); c = new GridBagConstraints(); c.gridx = 3; c.gridy = 0; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; c.insets = new Insets(0, 5, 0, 0); keyStoreSettingsPanel.add(keyStoreTypeCombo, c); c = new GridBagConstraints(); c.gridx = 1; c.gridy = 3; c.weightx = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(5, 0, 0, 0); add(keyStoreSettingsPanel, c); // --- TrustStore ------------------------------------------------------ // trustStoreLocLabel trustStoreLocCheckBox = new JCheckBox(); Mnemonics.setLocalizedText(trustStoreLocCheckBox, NbBundle.getMessage( SecurityOptionsPanel.class, "CHK_TrustStore")); // NOI18N trustStoreLocCheckBox.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.TRUSTSTORE_LOCATION)); // NOI18N trustStoreLocCheckBox.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { update(); } }); c = new GridBagConstraints(); c.gridx = 0; c.gridy = 5; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(20, 10, 0, 0); add(trustStoreLocCheckBox, c); // trustStoreField trustStoreLocField = new JTextField(); trustStoreLocField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.TRUSTSTORE_LOCATION)); // NOI18N trustStoreLocField.setPreferredSize( new Dimension(250, trustStoreLocField.getPreferredSize().height)); trustStoreLocField.getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { update(); } public void removeUpdate(DocumentEvent e) { update(); } public void changedUpdate(DocumentEvent e) { update(); } }); c = new GridBagConstraints(); c.gridx = 1; c.gridy = 5; c.gridwidth = 1; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(20, 5, 0, 0); add(trustStoreLocField, c); // trustStoreLocButton trustStoreLocButton = new JButton(); Mnemonics.setLocalizedText(trustStoreLocButton, NbBundle.getMessage(SecurityOptionsPanel.class, "BTN_Browse2")); // NOI18N trustStoreLocButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { File currentFile = new File(trustStoreLocField.getText().trim()); File file = PersistenceSupport.chooseLoadFile( NbBundle.getMessage(SecurityOptionsPanel.class, "CAP_SelectTrustStore"), currentFile); // NOI18N if (file != null) trustStoreLocField.setText(file.toString()); } }); c = new GridBagConstraints(); c.gridx = 2; c.gridy = 5; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(20, 5, 0, 0); add(trustStoreLocButton, c); // trustStoreSettingsPanel JPanel trustStoreSettingsPanel = new JPanel(new GridBagLayout()); // trustStorePassLabel trustStorePassLabel = new JLabel(); Mnemonics.setLocalizedText(trustStorePassLabel, NbBundle.getMessage( SecurityOptionsPanel.class, "LBL_Password2")); // NOI18N trustStorePassLabel.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.TRUSTSTORE_PASSWORD)); // NOI18N c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 5, 0, 0); trustStoreSettingsPanel.add(trustStorePassLabel, c); // trustStorePassField trustStorePassField = new JPasswordField(); trustStorePassLabel.setLabelFor(trustStorePassField); trustStorePassField.getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { update(); } public void removeUpdate(DocumentEvent e) { update(); } public void changedUpdate(DocumentEvent e) { update(); } }); trustStorePassField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.TRUSTSTORE_PASSWORD)); // NOI18N c = new GridBagConstraints(); c.gridx = 1; c.gridy = 0; c.gridwidth = 1; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 5, 0, 0); trustStoreSettingsPanel.add(trustStorePassField, c); // trustStoreTypeLabel trustStoreTypeLabel = new JLabel(); Mnemonics.setLocalizedText(trustStoreTypeLabel, NbBundle.getMessage( SecurityOptionsPanel.class, "LBL_Type2")); // NOI18N trustStoreTypeLabel.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.TRUSTSTORE_TYPE)); // NOI18N c = new GridBagConstraints(); c.gridx = 2; c.gridy = 0; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; c.insets = new Insets(0, 25, 0, 0); trustStoreSettingsPanel.add(trustStoreTypeLabel, c); // trustStoreTypeCombo trustStoreTypeCombo = new JComboBox(new String[] { NbBundle.getMessage( SecurityOptionsPanel.class, "OPT_Default"), "jks", "pkcs12", "jceks" }) { // NOI18N public Dimension getMinimumSize() { return getPreferredSize(); } }; trustStoreTypeLabel.setLabelFor(trustStoreTypeCombo); trustStoreTypeCombo.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { update(); } }); trustStoreTypeCombo.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.TRUSTSTORE_TYPE)); // NOI18N trustStoreTypeCombo.setEditable(true); c = new GridBagConstraints(); c.gridx = 3; c.gridy = 0; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; c.insets = new Insets(0, 5, 0, 0); trustStoreSettingsPanel.add(trustStoreTypeCombo, c); c = new GridBagConstraints(); c.gridx = 1; c.gridy = 6; c.weightx = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(5, 0, 0, 0); add(trustStoreSettingsPanel, c); // --- Protocols ------------------------------------------------------- // protocolsSeparator SectionSeparator protocolsSeparator = UISupport.createSectionSeparator( NbBundle.getMessage(SecurityOptionsPanel.class, "SEP_Protocols")); // NOI18N c = new GridBagConstraints(); c = new GridBagConstraints(); c.gridy = 7; c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(18, 0, 0, 0); add(protocolsSeparator, c); // protocolsCheckBox protocolsCheckBox = new JCheckBox(); Mnemonics.setLocalizedText(protocolsCheckBox, NbBundle.getMessage( SecurityOptionsPanel.class, "CHK_Protocols")); // NOI18N protocolsCheckBox.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.ENABLED_PROTOCOLS)); // NOI18N protocolsCheckBox.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { update(); } }); c = new GridBagConstraints(); c.gridx = 0; c.gridy = 8; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(7, 15, 0, 0); add(protocolsCheckBox, c); // protocolsField protocolsField = new JTextField(); protocolsField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.ENABLED_PROTOCOLS)); // NOI18N protocolsField.setPreferredSize( new Dimension(250, protocolsField.getPreferredSize().height)); protocolsField.getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { update(); } public void removeUpdate(DocumentEvent e) { update(); } public void changedUpdate(DocumentEvent e) { update(); } }); c = new GridBagConstraints(); c.gridx = 1; c.gridy = 8; c.gridwidth = 1; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(7, 5, 0, 0); add(protocolsField, c); // protocolsButton protocolsButton = new JButton(); Mnemonics.setLocalizedText(protocolsButton, NbBundle.getMessage( SecurityOptionsPanel.class, "BTN_Customize1")); // NOI18N protocolsButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String protocols = ValuesCustomizer.customize( ValuesCustomizer.PROTOCOLS, protocolsField.getText().trim()); if (protocols != null) protocolsField.setText(protocols); } }); c = new GridBagConstraints(); c.gridx = 2; c.gridy = 8; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(7, 5, 0, 0); add(protocolsButton, c); // cipherSuitesCheckBox cipherSuitesCheckBox = new JCheckBox(); Mnemonics.setLocalizedText(cipherSuitesCheckBox, NbBundle.getMessage( SecurityOptionsPanel.class, "CHK_CipherSuites")); // NOI18N cipherSuitesCheckBox.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.ENABLED_CIPHER_SUITES)); // NOI18N cipherSuitesCheckBox.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { update(); } }); c = new GridBagConstraints(); c.gridx = 0; c.gridy = 9; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(5, 15, 0, 0); add(cipherSuitesCheckBox, c); // cipherSuitesField cipherSuitesField = new JTextField(); cipherSuitesField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class, "MSG_ValueOf", SecurityModel.ENABLED_CIPHER_SUITES)); // NOI18N cipherSuitesField.setPreferredSize( new Dimension(250, cipherSuitesField.getPreferredSize().height)); cipherSuitesField.getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { update(); } public void removeUpdate(DocumentEvent e) { update(); } public void changedUpdate(DocumentEvent e) { update(); } }); c = new GridBagConstraints(); c.gridx = 1; c.gridy = 9; c.gridwidth = 1; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(5, 5, 0, 0); add(cipherSuitesField, c); // cipherSuitesButton cipherSuitesButton = new JButton(); Mnemonics.setLocalizedText(cipherSuitesButton, NbBundle.getMessage( SecurityOptionsPanel.class, "BTN_Customize2")); // NOI18N cipherSuitesButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String cipherSuites = ValuesCustomizer.customize( ValuesCustomizer.CIPHER_SUITES, cipherSuitesField.getText().trim()); if (cipherSuites != null) cipherSuitesField.setText(cipherSuites); } }); c = new GridBagConstraints(); c.gridx = 2; c.gridy = 9; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(5, 5, 0, 0); add(cipherSuitesButton, c); // --- Export / Import ----------------------------------------------------- // exportImportSeparator SectionSeparator exportImportSeparator = UISupport.createSectionSeparator( NbBundle.getMessage(SecurityOptionsPanel.class, "SEP_ExportImport")); // NOI18N c = new GridBagConstraints(); c.gridy = 10; c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(18, 0, 0, 0); add(exportImportSeparator, c); // exportImportPanel JPanel exportImportPanel = new JPanel(new GridBagLayout()); // loadFromFileButton loadFromFileButton = new JButton(); Mnemonics.setLocalizedText(loadFromFileButton, NbBundle.getMessage( SecurityOptionsPanel.class, "BTN_LoadFromFile")); // NOI18N loadFromFileButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { PersistenceSupport.loadFromFile(SecurityOptionsPanel.this); } }); c = new GridBagConstraints(); c.gridx = 1; c.gridy = 0; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.EAST; c.insets = new Insets(0, 5, 0, 0); exportImportPanel.add(loadFromFileButton, c); // saveToFileButton saveToFileButton = new JButton(); Mnemonics.setLocalizedText(saveToFileButton, NbBundle.getMessage( SecurityOptionsPanel.class, "BTN_SaveToFile")); // NOI18N saveToFileButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { PersistenceSupport.saveToFile(SecurityOptionsPanel.this); } }); c = new GridBagConstraints(); c.gridx = 2; c.gridy = 0; c.gridwidth = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; c.insets = new Insets(0, 5, 0, 0); exportImportPanel.add(saveToFileButton, c); c = new GridBagConstraints(); c.gridy = 11; c.weightx = 1; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; c.insets = new Insets(7, 0, 0, 0); add(exportImportPanel, c); // hintPanel hintPanel = new JPanel(new GridBagLayout()); hintPanel.setVisible(false); // hintLabel JLabel hintLabel = new JLabel(); Mnemonics.setLocalizedText(hintLabel, NbBundle.getMessage( SecurityOptionsPanel.class, "MSG_RestartVisualVM")); // NOI18N hintLabel.setIcon(ImageUtilities.loadImageIcon( "org/graalvm/visualvm/modules/security/resources/infoIcon.png", false)); // NOI18N) hintLabel.setIconTextGap(10); c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.weightx = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 0, 0, 0); hintPanel.add(hintLabel, c); // restartCheckBox restartCheckBox = new JCheckBox(); Mnemonics.setLocalizedText(restartCheckBox, NbBundle.getMessage( SecurityOptionsPanel.class, "CHK_RestartVisualVM")); // NOI18N c = new GridBagConstraints(); c.gridx = 0; c.gridy = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 20, 0, 0); hintPanel.add(restartCheckBox, c); // --- Filler --- c = new GridBagConstraints(); c.gridx = 0; c.gridy = 12; c.weighty = 1; c.anchor = GridBagConstraints.NORTHWEST; c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; add(Spacer.create(), c); c = new GridBagConstraints(); c.gridy = 13; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(30, 0, 0, 0); add(hintPanel, c); } private JTextArea notificationArea; private JCheckBox keyStoreLocCheckBox; private JTextField keyStoreLocField; private JButton keyStoreLocButton; private JLabel keyStorePassLabel; private JPasswordField keyStorePassField; private JLabel keyStoreTypeLabel; private JComboBox keyStoreTypeCombo; private JCheckBox trustStoreLocCheckBox; private JTextField trustStoreLocField; private JButton trustStoreLocButton; private JLabel trustStorePassLabel; private JPasswordField trustStorePassField; private JLabel trustStoreTypeLabel; private JComboBox trustStoreTypeCombo; private JCheckBox protocolsCheckBox; private JTextField protocolsField; private JButton protocolsButton; private JCheckBox cipherSuitesCheckBox; private JTextField cipherSuitesField; private JButton cipherSuitesButton; private JButton loadFromFileButton; private JButton saveToFileButton; private JPanel hintPanel; private JCheckBox restartCheckBox; } ================================================ FILE: plugins/security/src/org/graalvm/visualvm/modules/security/SecurityOptionsPanelController.java ================================================ /* * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.security; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.Arrays; import javax.swing.JComponent; import org.graalvm.visualvm.core.options.UISupport; import org.netbeans.spi.options.OptionsPanelController; import org.openide.LifecycleManager; import org.openide.util.HelpCtx; import org.openide.util.Lookup; @OptionsPanelController.TopLevelRegistration( id = "SecurityOptions", categoryName = "#OptionsCategory_Name_Security", iconBase = "org/graalvm/visualvm/modules/security/resources/security.png", position = 3000 ) public class SecurityOptionsPanelController extends OptionsPanelController { private SecurityModel model = SecurityModel.getInstance(); private SecurityOptionsPanel panel; private JComponent component; private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private boolean changed; public void update() { SecurityOptionsPanel p = getPanel(); p.setKeyStore(model.getKeyStore()); p.setKeyStorePassword(model.getKeyStorePassword()); p.setKeyStoreType(model.getKeyStoreType()); p.setTrustStore(model.getTrustStore()); p.setTrustStorePassword(model.getTrustStorePassword()); p.setTrustStoreType(model.getTrustStoreType()); p.setEnabledProtocols(model.getEnabledProtocols()); p.setEnabledCipherSuites(model.getEnabledCipherSuites()); p.resetRestart(); } public void applyChanges() { SecurityOptionsPanel p = getPanel(); model.setKeyStore(p.getKeyStore()); model.setKeyStorePassword(p.getKeyStorePassword()); model.setKeyStoreType(p.getKeyStoreType()); model.setTrustStore(p.getTrustStore()); model.setTrustStorePassword(p.getTrustStorePassword()); model.setTrustStoreType(p.getTrustStoreType()); model.setEnabledProtocols(p.getEnabledProtocols()); model.setEnabledCipherSuites(p.getEnabledCipherSuites()); if (p.shouldRestart() && differsFromEnv()) { LifecycleManager lcm = LifecycleManager.getDefault(); lcm.markForRestart(); lcm.exit(); } } public void cancel() { getPanel().cleanup(); } public boolean isValid() { return getPanel().dataValid(); } public boolean isChanged() { SecurityOptionsPanel p = getPanel(); if (!equals(p.getKeyStore(), model.getKeyStore())) return true; if (!equals(p.getKeyStorePassword(), model.getKeyStorePassword())) return true; if (!equals(p.getKeyStoreType(), model.getKeyStoreType())) return true; if (!equals(p.getTrustStore(), model.getTrustStore())) return true; if (!equals(p.getTrustStorePassword(), model.getTrustStorePassword())) return true; if (!equals(p.getTrustStoreType(), model.getTrustStoreType())) return true; if (!equals(p.getEnabledProtocols(), model.getEnabledProtocols())) return true; if (!equals(p.getEnabledCipherSuites(), model.getEnabledCipherSuites())) return true; return false; } public boolean differsFromEnv() { SecurityOptionsPanel p = getPanel(); if (!equals(p.getKeyStore(), SecurityModel.getKeyStoreEnv())) return true; if (!equals(p.getKeyStorePassword(), SecurityModel.getKeyStorePasswordEnv())) return true; if (!equals(p.getKeyStoreType(), SecurityModel.getKeyStoreTypeEnv())) return true; if (!equals(p.getTrustStore(), SecurityModel.getTrustStoreEnv())) return true; if (!equals(p.getTrustStorePassword(), SecurityModel.getTrustStorePasswordEnv())) return true; if (!equals(p.getTrustStoreType(), SecurityModel.getTrustStoreTypeEnv())) return true; if (!equals(p.getEnabledProtocols(), SecurityModel.getEnabledProtocolsEnv())) return true; if (!equals(p.getEnabledCipherSuites(), SecurityModel.getEnabledCipherSuitesEnv())) return true; return false; } public HelpCtx getHelpCtx() { return null; } public JComponent getComponent(Lookup masterLookup) { return getComponent(); } public void addPropertyChangeListener(PropertyChangeListener l) { pcs.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { pcs.removePropertyChangeListener(l); } SecurityModel getModel() { return SecurityModel.getInstance(); } private SecurityOptionsPanel getPanel() { if (panel == null) panel = new SecurityOptionsPanel(this); return panel; } private JComponent getComponent() { if (component == null) { component = UISupport.createScrollableContainer(getPanel()); } return component; } void changed() { if (!changed) { changed = true; pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true); } pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null); } private boolean equals(String o1, String o2) { if (o1 == null && o2 == null) return true; if (o1 != null && o1.equals(o2)) return true; return false; } private boolean equals(char[] ch1, char[] ch2) { if (ch1 == null && ch2 == null) return true; return Arrays.equals(ch1, ch2); } } ================================================ FILE: plugins/security/src/org/graalvm/visualvm/modules/security/ValuesCustomizer.java ================================================ /* * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.security; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dialog; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.net.Socket; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import javax.net.SocketFactory; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.BoundedRangeModel; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.KeyStroke; import javax.swing.ScrollPaneConstants; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TableColumnModelEvent; import javax.swing.event.TableColumnModelListener; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import org.graalvm.visualvm.uisupport.UISupport; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; import org.openide.awt.Mnemonics; import org.openide.util.NbBundle; /** * * @author Jiri Sedlacek */ abstract class ValuesCustomizer extends JPanel { // --- Private UI constants ------------------------------------------------ private static final Color DEFAULT_GRID_COLOR = new Color(240, 240, 240); // --- Public customizer types --------------------------------------------- static final ValuesCustomizer PROTOCOLS = new Protocols(); static final ValuesCustomizer CIPHER_SUITES = new CipherSuites(); // --- Public entrypoint --------------------------------------------------- static String customize(final ValuesCustomizer customizer, String selectedValues) { customizer.init(selectedValues); final DialogDescriptor dd = new DialogDescriptor(customizer, customizer.dialogTitle(), true, null); final Dialog d = DialogDisplayer.getDefault().createDialog(dd); d.pack(); SwingUtilities.invokeLater(new Runnable() { public void run() { customizer.onShown(); } }); d.setVisible(true); String result = dd.getValue() != DialogDescriptor.OK_OPTION ? null : customizer.getSelectedCipherSuites(); customizer.cleanup(); return result; } // --- Predefined customizers ---------------------------------------------- private static class Protocols extends ValuesCustomizer { private String[] allValues; String dialogTitle() { return NbBundle.getMessage(ValuesCustomizer.class, "CAP_SelectProtocols"); // NOI18N } String hintText() { return NbBundle.getMessage(ValuesCustomizer.class, "HINT_SelectProtocols"); // NOI18N } String valueName() { return NbBundle.getMessage(ValuesCustomizer.class, "COL_Protocols"); // NOI18N } synchronized String[] allValues() { if (allValues == null) { SocketFactory f = SSLSocketFactory.getDefault(); if (!(f instanceof SSLSocketFactory)) allValues = new String[0]; try { Socket s = ((SSLSocketFactory)f).createSocket(); if (!(s instanceof SSLSocket)) allValues = new String[0]; allValues = ((SSLSocket)s).getSupportedProtocols(); } catch (Exception e) { allValues = new String[0]; } } return allValues; } } private static class CipherSuites extends ValuesCustomizer { private String[] allValues; String dialogTitle() { return NbBundle.getMessage(ValuesCustomizer.class, "CAP_SelectCipherSuites"); // NOI18N } String hintText() { return NbBundle.getMessage(ValuesCustomizer.class, "HINT_SelectCipherSuites"); // NOI18N } String valueName() { return NbBundle.getMessage(ValuesCustomizer.class, "COL_CipherSuites"); // NOI18N } synchronized String[] allValues() { if (allValues == null) { SocketFactory f = SSLSocketFactory.getDefault(); if (!(f instanceof SSLSocketFactory)) allValues = new String[0]; allValues = ((SSLSocketFactory)f).getSupportedCipherSuites(); } return allValues; } } // --- Abstract interface -------------------------------------------------- abstract String dialogTitle(); abstract String hintText(); abstract String valueName(); abstract String[] allValues(); // --- Private implementation ---------------------------------------------- private void init(String selectedValues) { initModels(selectedValues); initComponents(); } private void onShown() { table.requestFocusInWindow(); } private String getSelectedCipherSuites() { StringBuilder b = new StringBuilder(); for (int i = 0; i < model.getRowCount(); i++) if (Boolean.TRUE.equals(model.getValueAt(i, 1))) b.append(model.getValueAt(i, 0).toString() + ","); // NOI18N int length = b.length(); if (length > 0) b.deleteCharAt(length - 1); return b.toString(); } private void cleanup() { removeAll(); table = null; model = null; } private void initModels(String selectedValues) { String[] allValuesArr = allValues(); String[] selectedValuesArr = selectedValues(selectedValues); final String[] cipherSuites = mergedValues(allValuesArr, selectedValuesArr); final boolean[] selectedMask = selectedValuesMask(cipherSuites, selectedValuesArr); final int rowsCount = cipherSuites.length; model = new DefaultTableModel() { public int getRowCount() { return rowsCount; } public int getColumnCount() { return 2; } public String getColumnName(int columnIndex) { if (columnIndex == 0) return valueName(); else return NbBundle.getMessage(ValuesCustomizer.class, "COL_Enabled"); // NOI18N } public Class getColumnClass(int columnIndex) { if (columnIndex == 0) return String.class; else return Boolean.class; } public boolean isCellEditable(int rowIndex, int columnIndex) { if (columnIndex == 0) return false; else return true; } public Object getValueAt(int rowIndex, int columnIndex) { if (columnIndex == 0) return cipherSuites[rowIndex]; else return selectedMask[rowIndex]; } public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if (columnIndex == 1) selectedMask[rowIndex] = (Boolean)aValue; } }; } private static String[] selectedValues(String selectedValues) { StringTokenizer st = new StringTokenizer(selectedValues, ","); // NOI18N String[] cipherSuites = new String[st.countTokens()]; for (int i = 0; i < cipherSuites.length; i++) cipherSuites[i] = st.nextToken(); return cipherSuites; } private static String[] mergedValues(String[] supported, String[] selected) { List supportedList = Arrays.asList(supported); List selectedList = Arrays.asList(selected); Set mergedSet = new HashSet(supportedList); mergedSet.addAll(selectedList); List merged = new ArrayList(mergedSet); Collections.sort(merged); return merged.toArray(new String[merged.size()]); } private static boolean[] selectedValuesMask(String[] allValues, String[] selectedValues) { boolean[] mask = new boolean[allValues.length]; List selectedValuesList = Arrays.asList(selectedValues); for (int i = 0; i < mask.length; i++) if (selectedValuesList.contains(allValues[i])) mask[i] = true; return mask; } private void setAllSelected(boolean selected) { for (int i = 0; i < model.getRowCount(); i++) model.setValueAt(selected, i, 1); model.fireTableDataChanged(); } private void initComponents() { // hintLabel JLabel hintLabel = new JLabel(); Mnemonics.setLocalizedText(hintLabel, hintText()); // table table = new JTable(model) { protected void processMouseEvent(MouseEvent e) { MouseEvent eventToDispatch = e; Point p = e.getPoint(); int column = columnAtPoint(p); if (column != 1) { int row = rowAtPoint(p); Rectangle cellRect = getCellRect(row, 1, false); p.x = cellRect.x + 1; eventToDispatch = new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(), e.getModifiers(), p.x, p.y, e.getClickCount(), e.isPopupTrigger(), e.getButton()); } super.processMouseEvent(eventToDispatch); } protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { getColumnModel().getSelectionModel().setSelectionInterval(1, 1); return super.processKeyBinding(ks, e, condition, pressed); } protected void initializeLocalVars() { super.initializeLocalVars(); setPreferredScrollableViewportSize(new Dimension(450, 300)); } }; hintLabel.setLabelFor(table); table.setOpaque(true); table.setBackground(UISupport.getDefaultBackground()); table.setRowHeight(defaultRowHeight() + 4); table.setRowMargin(0); table.setAutoCreateRowSorter(true); table.setShowHorizontalLines(false); table.setShowVerticalLines(true); table.setGridColor(DEFAULT_GRID_COLOR); table.setDefaultRenderer(String.class, new Renderer( table.getDefaultRenderer(String.class))); table.setDefaultRenderer(Boolean.class, new BooleanRenderer( table.getDefaultRenderer(Boolean.class))); table.getColumnModel().setColumnMargin(1); TableColumn c = table.getColumnModel().getColumn(1); c.setMaxWidth(c.getPreferredWidth()); c.setResizable(false); // viewport JViewport viewport = new Viewport(table); // tableScroll JScrollPane tableScroll = new JScrollPane( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); tableScroll.setViewport(viewport); final JScrollBar vScrollBar = tableScroll.getVerticalScrollBar(); final BoundedRangeModel vScrollBarModel = vScrollBar.getModel(); vScrollBarModel.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { vScrollBar.setEnabled(vScrollBarModel.getExtent() != vScrollBarModel.getMaximum()); } }); // cornerButton final JButton cornerButton = new JButton(); cornerButton.setDefaultCapable(false); cornerButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JMenuItem selectAll = new JMenuItem (new AbstractAction() { public void actionPerformed(ActionEvent e) { setAllSelected(true); } }); Mnemonics.setLocalizedText(selectAll, NbBundle.getMessage( ValuesCustomizer.class, "ACT_SelectAll")); // NOI18N JMenuItem deselectAll = new JMenuItem(new AbstractAction() { public void actionPerformed(ActionEvent e) { setAllSelected(false); } }); Mnemonics.setLocalizedText(deselectAll, NbBundle.getMessage( ValuesCustomizer.class, "ACT_DeselectAll")); // NOI18N JPopupMenu popup = new JPopupMenu(); popup.add(selectAll); popup.add(deselectAll); Dimension s = popup.getPreferredSize(); popup.show(cornerButton, cornerButton.getWidth() / 2 - s.width, cornerButton.getHeight() / 2); } }); tableScroll.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, cornerButton); // this setOpaque(false); setBorder(BorderFactory.createEmptyBorder(15, 10, 5, 10)); setLayout(new BorderLayout(5, 5)); add(hintLabel, BorderLayout.NORTH); add(tableScroll, BorderLayout.CENTER); } private static int defaultRowHeight() { return new JLabel("X").getPreferredSize().height + 4; // NOI18N } private ValuesCustomizer() {} private DefaultTableModel model; private JTable table; private static class Renderer implements TableCellRenderer { private static final Color BACKGROUND; private static final Color DARKER_BACKGROUND; static { BACKGROUND = UISupport.getDefaultBackground(); int darkerR = BACKGROUND.getRed() - 11; if (darkerR < 0) darkerR += 26; int darkerG = BACKGROUND.getGreen() - 11; if (darkerG < 0) darkerG += 26; int darkerB = BACKGROUND.getBlue() - 11; if (darkerB < 0) darkerB += 26; DARKER_BACKGROUND = new Color(darkerR, darkerG, darkerB); } private TableCellRenderer impl; Renderer(TableCellRenderer impl) { this.impl = impl; } protected Object formatValue(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { return value; } protected void updateRenderer(Component c, JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (!isSelected) { c.setBackground(row % 2 == 0 ? DARKER_BACKGROUND : BACKGROUND); // Make sure the renderer paints its background (Nimbus) if (c instanceof JComponent) ((JComponent)c).setOpaque(true); } } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (impl == null) impl = table.getDefaultRenderer(table.getColumnClass(column)); value = formatValue(table, value, isSelected, false, row, column); Component c = impl.getTableCellRendererComponent(table, value, isSelected, false, row, column); updateRenderer(c, table, value, isSelected, false, row, column); return c; } } private static class BooleanRenderer extends Renderer { BooleanRenderer(TableCellRenderer renderer) { super(renderer); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // Workaround strange selection behavior for newly selected checkbox isSelected = isSelected || hasFocus; return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); } } private static class Viewport extends JViewport { private final JTable view; private final Color background; Viewport(JTable view) { super(); setView(view); this.view = view; setOpaque(true); background = view.getBackground(); setBackground(background); view.getColumnModel().addColumnModelListener(new TableColumnModelListener() { public void columnAdded(TableColumnModelEvent e) { repaint(); } public void columnMoved(TableColumnModelEvent e) { repaint(); } public void columnRemoved(TableColumnModelEvent e) { repaint(); } public void columnMarginChanged(ChangeEvent e) { repaint(); } public void columnSelectionChanged(ListSelectionEvent e) {} }); } protected void paintComponent(Graphics g) { super.paintComponent(g); paintVerticalLines(g); } private void paintVerticalLines(Graphics g) { int height = getHeight(); int viewHeight = view.getHeight(); if (viewHeight >= height) return; g.setColor(background); g.fillRect(0, viewHeight, getWidth(), getHeight() - viewHeight); int cellX = 0; int cellWidth; TableColumnModel model = view.getColumnModel(); int columnCount = model.getColumnCount(); g.setColor(DEFAULT_GRID_COLOR); for (int i = 0; i < columnCount; i++) { cellWidth = model.getColumn(i).getWidth(); cellX += cellWidth; g.drawLine(cellX - 1, viewHeight, cellX - 1, height); } } } } ================================================ FILE: plugins/startupprofiler/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.profiler.startup. ================================================ FILE: plugins/startupprofiler/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.profiler.startup/2 OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/profiler/startup/Bundle.properties OpenIDE-Module-Layer: org/graalvm/visualvm/profiler/startup/resources/layer.xml OpenIDE-Module-Specification-Version: 2.0 ================================================ FILE: plugins/startupprofiler/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/startupprofiler/nbproject/project.properties ================================================ javac.source=1.6 javac.compilerargs=-Xlint -Xlint:-serial license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Jiri Sedlacek ================================================ FILE: plugins/startupprofiler/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.profiler.startup org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.profiler 2 2.0 org.graalvm.visualvm.profiling 2 2.0 org.graalvm.visualvm.uisupport 2 2.0 org.openide.dialogs 7.28.1 org.openide.modules 7.35.1 org.openide.util 9.8 org.openide.util.ui 9.8 ================================================ FILE: plugins/startupprofiler/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/Bundle.properties ================================================ # # Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Profiling OpenIDE-Module-Long-Description=\ Startup Profiler plugin enables instrumented profiling of local applications from their startup. \ Java 5+ applications started by the user running VisualVM are supported. \ See the online documentation for more. OpenIDE-Module-Name=Startup Profiler OpenIDE-Module-Short-Description=Startup Profiler Toolbars/StartupProfiler=S&tartup Profiler ================================================ FILE: plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/Dialogs.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.profiler.startup; import java.awt.Dialog; import java.awt.Image; import java.awt.Window; import java.lang.ref.WeakReference; import java.util.List; import javax.swing.SwingUtilities; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; /** * * @author Jiri Sedlacek */ final class Dialogs { private static WeakReference> icons; static Dialog dialog(String caption, Object message) { return dialogImpl(caption, message, DialogDescriptor.PLAIN_MESSAGE); } static Dialog info(String caption, String message) { return dialogImpl(caption, message, DialogDescriptor.INFORMATION_MESSAGE, DialogDescriptor.OK_OPTION); } static Dialog warning(String caption, String message) { return dialogImpl(caption, message, DialogDescriptor.WARNING_MESSAGE, DialogDescriptor.OK_OPTION); } static Dialog error(String caption, String message) { return dialogImpl(caption, message, DialogDescriptor.ERROR_MESSAGE, DialogDescriptor.OK_OPTION); } private static Dialog dialogImpl(String caption, Object message, int type, Object... options) { DialogDescriptor dd = new DialogDescriptor(message, caption); dd.setMessageType(type); dd.setOptions(options); Dialog d = DialogDisplayer.getDefault().createDialog(dd); d.setIconImages(getIcons()); d.setResizable(false); return d; } private static List getIcons() { List i = icons == null ? null : icons.get(); if (i == null) for (Window w : Dialog.getWindows()) { List images = w.getIconImages(); if (images != null && !images.isEmpty()) { i = images; icons = new WeakReference(images); break; } } return i; } static void show(final Dialog d) { Runnable r = new Runnable() { public void run() { d.setVisible(true); } }; if (SwingUtilities.isEventDispatchThread()) r.run(); else SwingUtilities.invokeLater(r); } } ================================================ FILE: plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/StartupConfigurator.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.profiler.startup; import org.graalvm.visualvm.core.ui.DesktopUtils; import org.graalvm.visualvm.core.ui.components.SectionSeparator; import org.graalvm.visualvm.profiler.CPUSettingsSupport; import org.graalvm.visualvm.profiler.JDBCSettingsSupport; import org.graalvm.visualvm.profiler.MemorySettingsSupport; import org.graalvm.visualvm.profiler.ProfilerSettingsSupport; import org.graalvm.visualvm.profiler.ProfilerSupport; import org.graalvm.visualvm.profiling.presets.PresetSelector; import org.graalvm.visualvm.profiling.presets.ProfilerPreset; import org.graalvm.visualvm.profiling.presets.ProfilerPresets; import org.graalvm.visualvm.uisupport.HorizontalLayout; import org.graalvm.visualvm.uisupport.SeparatorLine; import org.graalvm.visualvm.uisupport.UISupport; import org.graalvm.visualvm.uisupport.VerticalLayout; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Insets; import java.awt.Point; import java.awt.Toolkit; import java.awt.Window; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.net.URI; import java.util.ArrayList; import java.util.List; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.DefaultComboBoxModel; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.JTextArea; import javax.swing.SpinnerNumberModel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.text.Caret; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; /** * * @author Jiri Sedlacek */ @NbBundle.Messages({ "HINT_ProfileStartup=Profile manually started local application from its startup. Follow these steps to start the profiling session.", "STEP_1=1. Specify application configuration:", "STEP_2=2. Define profiler settings:", "STEP_3=3. Setup profiled application:", "CAP_InvalidSettings=Invalid Profiler Settings", "MSG_InvalidCPUSettings=Provided CPU settings are invalid.", "MSG_InvalidMemorySettings=Provided memory settings are invalid.", "LBL_Continue=Continue >>>", "LBL_Platform=Platform:", "LBL_Architecture=Architecture:", "LBL_Port=Port:", "BTN_Profile=Profile", "LBL_Profile=Profile:", "LBL_CPU=CPU", "LBL_Memory=Memory", "LBL_JDBC=JDBC", "BTN_Clipboard=Copy to clipboard", "CAP_Clipboard=Copy to Clipboard", "MSG_Clipboard=Profiler parameter copied to clipboard", "HINT_ConfigureApp=Configure the application to run using {0} {1} and add the following parameter to its JVM arguments:", "STR_User=user {0}", "STR_CurrentUser=the current user", "HINT_StartApp=Click the Profile button to submit this dialog and then start the application as {0}.", "CAP_OnlineHelp=Online Help", "LBL_OnlineHelp=Online help", "MSG_OnlineHelp=Please open the following address in your browser:" }) final class StartupConfigurator { private static final String HELP = "https://visualvm.github.io/startupprofiler.html"; // NOI18N private static final String CPU_ICON_PATH = "org/graalvm/visualvm/profiler/startup/resources/cpu.png"; // NOI18N private static final String MEM_ICON_PATH = "org/graalvm/visualvm/profiler/startup/resources/memory.png"; // NOI18N private static final String JDBC_ICON_PATH = "org/graalvm/visualvm/profiler/startup/resources/jdbc.png"; // NOI18N private static final String HELP_ICON_PATH = "org/graalvm/visualvm/profiler/startup/resources/help.png"; // NOI18N private static final Icon CPU_ICON = ImageUtilities.loadImageIcon(CPU_ICON_PATH, false); private static final Icon MEM_ICON = ImageUtilities.loadImageIcon(MEM_ICON_PATH, false); private static final Icon JDBC_ICON = ImageUtilities.loadImageIcon(JDBC_ICON_PATH, false); private static final Icon HELP_ICON = ImageUtilities.loadImageIcon(HELP_ICON_PATH, false); private CPUSettingsSupport cpuSettings; private MemorySettingsSupport memorySettings; private JDBCSettingsSupport jdbcSettings; private DefaultComboBoxModel selectorModel; private List allSelectors; private JComponent ui; private boolean accepted; private JButton submit; private JTextArea start1; private JTextArea start2; private JTextArea param; private JPanel panel; private Dimension cpuSize; private Dimension memorySize; private Dimension jdbcSize; private JRadioButton cpuSelector; private JRadioButton memorySelector; private JRadioButton jdbcSelector; private JComboBox java; private JComboBox arch; private JSpinner port; private String[] javaPlatforms; private String[] architectures; StartupConfigurator() { cpuSettings = new CPUSettingsSupport() { public boolean presetValid() { return cpuSettings.settingsValid() && memorySettings.settingsValid() && jdbcSettings.settingsValid(); } public PresetSelector createSelector(Runnable presetSynchronizer) { return StartupConfigurator.this.createSelector(presetSynchronizer); } }; memorySettings = new MemorySettingsSupport() { public boolean presetValid() { return cpuSettings.settingsValid() && memorySettings.settingsValid() && jdbcSettings.settingsValid(); } public PresetSelector createSelector(Runnable presetSynchronizer) { return StartupConfigurator.this.createSelector(presetSynchronizer); } }; jdbcSettings = new JDBCSettingsSupport() { public boolean presetValid() { return cpuSettings.settingsValid() && memorySettings.settingsValid() && jdbcSettings.settingsValid(); } public PresetSelector createSelector(Runnable presetSynchronizer) { return StartupConfigurator.this.createSelector(presetSynchronizer); } }; // Warmup, the implementation expects both panels to be created cpuSettings.getComponent(); memorySettings.getComponent(); jdbcSettings.getComponent(); } private PresetSelector createSelector(Runnable presetSynchronizer) { if (selectorModel == null) selectorModel = new DefaultComboBoxModel(); if (allSelectors == null) allSelectors = new ArrayList(); PresetSelector selector = ProfilerPresets.getInstance().createSelector( selectorModel, allSelectors, presetSynchronizer); allSelectors.add(selector); return selector; } JComponent getUI() { accepted = false; if (ui == null) ui = createUI(); SwingUtilities.invokeLater(new Runnable() { public void run() { if (submit.isShowing()) submit.requestFocusInWindow(); } }); return ui; } boolean accepted() { return accepted; } ProfilerSettingsSupport getSettings() { if (cpuSelector.isSelected()) return cpuSettings; else if (memorySelector.isSelected()) return memorySettings; else if (jdbcSelector.isSelected()) return jdbcSettings; return null; } ProfilerPreset getPreset() { return (ProfilerPreset)selectorModel.getSelectedItem(); } String getJavaPlatform() { return javaPlatforms[java.getSelectedIndex()]; } int getArchitecture() { return Integer.parseInt(architectures[arch.getSelectedIndex()]); } int getPort() { return (Integer)port.getValue(); } private JComponent createUI() { JPanel header = new JPanel(new VerticalLayout(false)); header.setOpaque(true); JTextArea hint = new JTextArea(Bundle.HINT_ProfileStartup()); hint.setLineWrap(true); hint.setWrapStyleWord(true); hint.setEditable(false); hint.setFocusable(false); hint.setOpaque(false); if (UISupport.isNimbusLookAndFeel()) hint.setBackground(new Color(0, 0, 0, 0)); hint.setCaret(new NullCaret()); hint.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); header.add(hint); header.add(new SeparatorLine()); JPanel content = new JPanel(new VerticalLayout(false)); content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); content.setOpaque(false); content.add(new SectionSeparator(Bundle.STEP_1())); content.add(createAttachPanel()); final JPanel show2 = new JPanel(new BorderLayout()); show2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 3)); show2.setOpaque(false); show2.setVisible(false); content.add(show2); final JComponent separator2 = new SectionSeparator(Bundle.STEP_2()); final JComponent profilerP = createProfilePanel(); content.add(separator2); content.add(profilerP); final JPanel show3 = new JPanel(new BorderLayout()); show3.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 3)); show3.setOpaque(false); show3.setVisible(false); content.add(show3); final JComponent separator3 = new SectionSeparator(Bundle.STEP_3()); final JComponent stepsP = createStepsPanel(); content.add(separator3); content.add(stepsP); final JPanel footer = new JPanel(new VerticalLayout(false)); footer.setOpaque(true); footer.add(new SeparatorLine(), BorderLayout.NORTH); footer.add(createVerticalSpace(10)); JPanel buttons = new JPanel(new BorderLayout(0, 0)); JPanel buttonsL = new JPanel(new HorizontalLayout(false)); JButton help = new JButton(HELP_ICON) { protected void fireActionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { showHelp(null); } // NOI18N }); } public Dimension getPreferredSize() { Dimension d = submit.getPreferredSize(); d.width = d.height; return d; } }; help.setToolTipText(Bundle.LBL_OnlineHelp()); buttonsL.add(createHorizontalSpace(10)); buttonsL.add(help); JPanel buttonsR = new JPanel(new HorizontalLayout(false)); submit = new JButton(Bundle.BTN_Profile(), new ImageIcon(StartupProfilerAction.ICON)) { protected void fireActionPerformed(ActionEvent e) { String err = null; if (cpuSelector.isSelected()) { if (!cpuSettings.settingsValid()) err = Bundle.MSG_InvalidCPUSettings(); } else if (memorySelector.isSelected()) { if (!memorySettings.settingsValid()) err = Bundle.MSG_InvalidMemorySettings(); } if (err != null) { Dialogs.show(Dialogs.error(Bundle.CAP_InvalidSettings(), err)); } else { accepted = true; Window w = SwingUtilities.getWindowAncestor(this); if (w != null) w.setVisible(false); } } }; buttonsR.add(submit); // buttonsC.add(createHorizontalSpace(5)); // buttonsC.add(new JButton("Cancel") { // protected void fireActionPerformed(ActionEvent e) { // Window w = SwingUtilities.getWindowAncestor(this); // if (w != null) w.setVisible(false); // } // }); buttonsR.add(createHorizontalSpace(10)); buttons.add(buttonsL, BorderLayout.WEST); buttons.add(buttonsR, BorderLayout.EAST); footer.add(buttons); footer.add(createVerticalSpace(10)); // --- panel = new JPanel(new VerticalLayout(false)); panel.setBackground(UISupport.getDefaultBackground()); panel.setOpaque(true); panel.add(header); panel.add(content); panel.add(footer); // --- // Read the preferred dialog width to initialize textareas int width = panel.getPreferredSize().width; // Correctly layout multiline textareas hint.setSize(width - widthInsetsInContainer(hint, panel), Integer.MAX_VALUE); start1.setSize(width - widthInsetsInContainer(start1, panel), Integer.MAX_VALUE); start2.setSize(width - widthInsetsInContainer(start2, panel), Integer.MAX_VALUE); // Setup dialog size cpuSize = panel.getPreferredSize(); memorySize = new Dimension(cpuSize); memorySize.height -= cpuSettings.getComponent().getPreferredSize().height - memorySettings.getComponent().getPreferredSize().height; jdbcSize = new Dimension(cpuSize); jdbcSize.height -= cpuSettings.getComponent().getPreferredSize().height - jdbcSettings.getComponent().getPreferredSize().height; panel.setPreferredSize(cpuSize); separator2.setVisible(false); profilerP.setVisible(false); separator3.setVisible(false); stepsP.setVisible(false); footer.setVisible(false); show2.setVisible(true); JButton show2A = new JButton(HELP_ICON) { protected void fireActionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { showHelp("appconfig"); } // NOI18N }); } }; show2A.setToolTipText(Bundle.LBL_OnlineHelp()); show2A.setContentAreaFilled(false); show2A.setOpaque(false); show2A.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); show2A.setBorder(BorderFactory.createEmptyBorder(2, 3, 1, 3)); JButton show2B = new JButton("" + Bundle.LBL_Continue() + "") { // NOI18N protected void fireActionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { separator2.setVisible(true); profilerP.setVisible(true); show3.setVisible(true); show2.setVisible(false); } }); } }; show2B.setContentAreaFilled(false); show2B.setOpaque(false); show2B.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); show2B.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); JPanel show2P = new JPanel(new HorizontalLayout(false)); show2P.setOpaque(false); show2P.add(show2A); show2P.add(createHorizontalSpace(1)); show2P.add(show2B); show2.add(show2P, BorderLayout.EAST); JButton show3A = new JButton(HELP_ICON) { protected void fireActionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { showHelp("profsettings"); } // NOI18N }); } }; show3A.setToolTipText(Bundle.LBL_OnlineHelp()); show3A.setContentAreaFilled(false); show3A.setOpaque(false); show3A.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); show3A.setBorder(BorderFactory.createEmptyBorder(2, 3, 1, 3)); JButton show3B = new JButton("" + Bundle.LBL_Continue() + "") { // NOI18N protected void fireActionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { separator3.setVisible(true); stepsP.setVisible(true); footer.setVisible(true); show3.setVisible(false); } }); } }; show3B.setContentAreaFilled(false); show3B.setOpaque(false); show3B.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); show3B.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); JPanel show3P = new JPanel(new HorizontalLayout(false)); show3P.setOpaque(false); show3P.add(show3A); show3P.add(createHorizontalSpace(1)); show3P.add(show3B); show3.add(show3P, BorderLayout.EAST); return panel; } private JPanel createAttachPanel() { JPanel attach = new JPanel(new HorizontalLayout(false, 5)); attach.setBorder(BorderFactory.createEmptyBorder(5, 13, 15, 5)); attach.setOpaque(false); attach.add(new JLabel(Bundle.LBL_Platform())); String[][] platforms = ProfilerSupport.getInstance().getSupportedJavaPlatforms(); javaPlatforms = platforms[1]; java = new JComboBox(platforms[0]) { public Dimension getPreferredSize() { // Workaround for Nimbus LaF Dimension d = super.getPreferredSize(); if (UISupport.isNimbusLookAndFeel()) d.width += 5; return d; } protected void selectedItemChanged() { super.selectedItemChanged(); if (arch != null) { String[][] archs = ProfilerSupport.getInstance().getSupportedArchitectures(getJavaPlatform()); architectures = archs[1]; Object sel = arch.getSelectedItem(); arch.setModel(new DefaultComboBoxModel(archs[0])); if (sel == null) sel = archs[2][0]; if (sel != null) arch.setSelectedItem(sel); arch.setEnabled(arch.getItemCount() > 1); } updateParam(); } }; java.setEnabled(java.getItemCount() > 1); attach.add(java); attach.add(createHorizontalSpace(2)); attach.add(new JLabel(Bundle.LBL_Architecture())); arch = new JComboBox() { public Dimension getPreferredSize() { // Workaround for Nimbus LaF Dimension d = super.getPreferredSize(); if (UISupport.isNimbusLookAndFeel()) d.width += 5; return d; } protected void selectedItemChanged() { super.selectedItemChanged(); updateParam(); } }; java.setSelectedItem(platforms[2][0]); attach.add(arch); attach.add(createHorizontalSpace(2)); attach.add(new JLabel(Bundle.LBL_Port())); int portv = ProfilerSupport.getInstance().getDefaultPort(); port = new JSpinner(new SpinnerNumberModel(portv, 1, 65535, 1)); port.getModel().addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { updateParam(); } }); attach.add(port); return attach; } private JPanel createProfilePanel() { final JComponent cpu = cpuSettings.getComponent(); ((JComponent)cpu.getComponent(0)).setBorder(BorderFactory.createEmptyBorder(-3, -10, 0, -10)); ((JComponent)cpu.getComponent(1)).setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); final JComponent memory = memorySettings.getComponent(); ((JComponent)memory.getComponent(0)).setBorder(BorderFactory.createEmptyBorder(-3, -10, 0, -10)); ((JComponent)memory.getComponent(1)).setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); memory.setVisible(false); final JComponent jdbc = jdbcSettings.getComponent(); ((JComponent)jdbc.getComponent(0)).setBorder(BorderFactory.createEmptyBorder(-3, -10, 0, -10)); ((JComponent)jdbc.getComponent(1)).setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); jdbc.setVisible(false); final JPanel profile = new JPanel(new VerticalLayout(false)); profile.setBorder(BorderFactory.createEmptyBorder(5, 13, 15, 5)); profile.setOpaque(false); JPanel mode = new JPanel(new HorizontalLayout(false, 5)); mode.setOpaque(false); mode.add(new JLabel(Bundle.LBL_Profile())); final ButtonGroup bg = new ButtonGroup(); cpuSelector = new IconRadioButton(Bundle.LBL_CPU(), CPU_ICON, true) { boolean firstEvent = true; { bg.add(this); } protected void fireItemStateChanged(ItemEvent e) { super.fireItemStateChanged(e); if (e.getStateChange() == ItemEvent.SELECTED) { cpu.setVisible(true); memory.setVisible(false); jdbc.setVisible(false); if (panel != null) { panel.setPreferredSize(cpuSize); SwingUtilities.getWindowAncestor(profile).pack(); } } } }; mode.add(cpuSelector); memorySelector = new IconRadioButton(Bundle.LBL_Memory(), MEM_ICON, false) { { bg.add(this); } protected void fireItemStateChanged(ItemEvent e) { super.fireItemStateChanged(e); if (e.getStateChange() == ItemEvent.SELECTED) { cpu.setVisible(false); memory.setVisible(true); jdbc.setVisible(false); if (panel != null) { panel.setPreferredSize(memorySize); SwingUtilities.getWindowAncestor(profile).pack(); } } } }; mode.add(memorySelector); jdbcSelector = new IconRadioButton(Bundle.LBL_JDBC(), JDBC_ICON, false) { { bg.add(this); } protected void fireItemStateChanged(ItemEvent e) { super.fireItemStateChanged(e); if (e.getStateChange() == ItemEvent.SELECTED) { cpu.setVisible(false); memory.setVisible(false); jdbc.setVisible(true); if (panel != null) { panel.setPreferredSize(jdbcSize); SwingUtilities.getWindowAncestor(profile).pack(); } } } }; mode.add(jdbcSelector); profile.add(mode); profile.add(cpu); profile.add(memory); profile.add(jdbc); return profile; } private JPanel createStepsPanel() { JPanel steps = new JPanel(new VerticalLayout(false)); steps.setBorder(BorderFactory.createEmptyBorder(5, 13, 15, 5)); steps.setOpaque(false); start1 = new JTextArea(); start1.setLineWrap(true); start1.setWrapStyleWord(true); start1.setEditable(false); start1.setFocusable(false); start1.setOpaque(false); if (UISupport.isNimbusLookAndFeel()) start1.setBackground(new Color(0, 0, 0, 0)); start1.setCaret(new NullCaret()); start1.setBorder(BorderFactory.createEmptyBorder()); steps.add(start1); final JPanel arg = new JPanel(new BorderLayout(5, 0)); arg.setOpaque(false); TextAreaComponent paramA = createTextArea(1); param = paramA.getTextArea(); updateParam(); arg.add(paramA, BorderLayout.CENTER); JButton link = new JButton(Bundle.BTN_Clipboard()) { protected void fireActionPerformed(ActionEvent e) { RequestProcessor.getDefault().post(new Runnable() { public void run() { StringSelection s = new StringSelection(param.getText()); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s, s); Dialogs.show(Dialogs.info(Bundle.CAP_Clipboard(), Bundle.MSG_Clipboard())); } }); } }; arg.add(link, BorderLayout.EAST); steps.add(createVerticalSpace(8)); steps.add(arg); steps.add(createVerticalSpace(8)); String user = System.getProperty("user.name"); // NOI18N if (user != null) user = Bundle.STR_User(user); else user = Bundle.STR_CurrentUser(); start2 = new JTextArea(Bundle.HINT_StartApp(user)); start2.setLineWrap(true); start2.setWrapStyleWord(true); start2.setEditable(false); start2.setFocusable(false); start2.setOpaque(false); if (UISupport.isNimbusLookAndFeel()) start2.setBackground(new Color(0, 0, 0, 0)); start2.setCaret(new NullCaret()); start2.setBorder(BorderFactory.createEmptyBorder()); steps.add(start2); return steps; } private void updateParam() { if (param == null) return; start1.setText(Bundle.HINT_ConfigureApp(java.getSelectedItem().toString(), arch.getSelectedItem().toString())); int caret = param.getCaretPosition(); param.setText(ProfilerSupport.getInstance().getStartupParameter( getJavaPlatform(), getArchitecture(), getPort())); try { param.setCaretPosition(caret); } catch (IllegalArgumentException e) { param.setCaretPosition(0); } if (param.isShowing()) { final JComponent c = (JComponent)param.getParent().getParent(); c.setBorder(BorderFactory.createLineBorder(Color.RED)); RequestProcessor.getDefault().post(new Runnable() { public void run() { SwingUtilities.invokeLater(new Runnable() { public void run() { JComponent c = (JComponent)param.getParent().getParent(); c.setBorder(BorderFactory.createLineBorder(Color.GRAY)); } }); } }, 180); } } private static void showHelp(String section) { final String addr = (section == null) ? HELP : HELP + "#" + section; // NOI18N if (DesktopUtils.isBrowseAvailable()) { RequestProcessor.getDefault().post(new Runnable() { public void run() { try { URI uri = new URI(addr); DesktopUtils.browse(uri); } catch (Exception e) { showHelpDialog(addr); } } }); } else { showHelpDialog(addr); } } private static void showHelpDialog(final String addr) { SwingUtilities.invokeLater(new Runnable() { public void run() { Dialogs.show(Dialogs.info(Bundle.CAP_OnlineHelp(), Bundle.MSG_OnlineHelp() + "\n" + addr)); // NOI18N } }); } private static int widthInsetsInContainer(Container c, Container p) { int w = 0; while (c != null && p != null && c != p) { c = c.getParent(); Insets i = c.getInsets(); w += i.left + i.right; } return w; } private static JComponent createHorizontalSpace(final int width) { JPanel space = new JPanel(null) { public Dimension getPreferredSize() { return new Dimension(width, 0); } public Dimension getMinimumSize() { return getPreferredSize(); } public Dimension getMaximumSize() { return getPreferredSize(); } }; space.setOpaque(false); return space; } private static JComponent createVerticalSpace(final int height) { JPanel space = new JPanel(null) { public Dimension getPreferredSize() { return new Dimension(0, height); } public Dimension getMinimumSize() { return getPreferredSize(); } public Dimension getMaximumSize() { return getPreferredSize(); } }; space.setOpaque(false); return space; } private static TextAreaComponent createTextArea(int rows) { final JTextArea rootsArea = new JTextArea(); rootsArea.setEditable(false); rootsArea.setFont(new Font("Monospaced", Font.PLAIN, UIManager.getFont("Label.font").getSize())); // NOI18N TextAreaComponent rootsAreaScrollPane = new TextAreaComponent(rootsArea, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) { public Dimension getMinimumSize() { return getPreferredSize(); } public void setEnabled(boolean enabled) { super.setEnabled(enabled); rootsArea.setEnabled(enabled); } }; rootsAreaScrollPane.setBorder(BorderFactory.createLineBorder(Color.GRAY)); JTextArea referenceArea = new JTextArea("X"); // NOI18N referenceArea.setFont(rootsArea.getFont()); referenceArea.setRows(rows); Insets insets = rootsAreaScrollPane.getInsets(); rootsAreaScrollPane.setPreferredSize(new Dimension(1, referenceArea.getPreferredSize().height + (insets != null ? insets.top + insets.bottom : 0))); return rootsAreaScrollPane; } private static class TextAreaComponent extends JScrollPane { public TextAreaComponent(JTextArea textArea, int vPolicy, int hPolicy) { super(textArea, vPolicy, hPolicy); } public JTextArea getTextArea() { return (JTextArea)getViewport().getView(); } } private static class IconRadioButton extends JRadioButton { private static final int CHECKBOX_OFFSET = getCheckBoxOffset(); private final JRadioButton renderer; public IconRadioButton(String text, Icon icon, boolean selected) { renderer = new JRadioButton(text, icon) { public boolean hasFocus() { return IconRadioButton.this.hasFocus(); } }; renderer.setOpaque(false); renderer.setBorderPainted(false); setSelected(selected); setBorderPainted(false); setOpaque(false); } protected void paintComponent(Graphics g) { super.paintComponent(g); g.translate(renderer.getX(), renderer.getY()); renderer.paint(g); g.translate(-renderer.getX(), -renderer.getY()); } public void setBounds(int x, int y, int width, int height) { Dimension d = super.getPreferredSize(); renderer.setBounds(d.width - CHECKBOX_OFFSET, 0, width - d.width + CHECKBOX_OFFSET, height); super.setBounds(x, y, width, height); } public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); d.width += renderer.getPreferredSize().width - CHECKBOX_OFFSET; return d; } private static int getCheckBoxOffset() { if (UISupport.isWindowsLookAndFeel()) return 3; else if (UISupport.isNimbusLookAndFeel()) return -3; else if (UISupport.isMetalLookAndFeel()) return 3; else if (UISupport.isAquaLookAndFeel()) return 6; else return 0; } } private static final class NullCaret implements Caret { public void install(javax.swing.text.JTextComponent c) {} public void deinstall(javax.swing.text.JTextComponent c) {} public void paint(Graphics g) {} public void addChangeListener(ChangeListener l) {} public void removeChangeListener(ChangeListener l) {} public boolean isVisible() { return false; } public void setVisible(boolean v) {} public boolean isSelectionVisible() { return false; } public void setSelectionVisible(boolean v) {} public void setMagicCaretPosition(Point p) {} public Point getMagicCaretPosition() { return new Point(0, 0); } public void setBlinkRate(int rate) {} public int getBlinkRate() { return 0; } public int getDot() { return 0; } public int getMark() { return 0; } public void setDot(int dot) {} public void moveDot(int dot) {} } } ================================================ FILE: plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/StartupProfiler.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.profiler.startup; import org.graalvm.visualvm.profiler.ProfilerSettingsSupport; import org.graalvm.visualvm.profiler.ProfilerSupport; import org.graalvm.visualvm.profiling.presets.ProfilerPreset; import java.awt.Dialog; import javax.swing.SwingUtilities; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; /** * * @author Jiri Sedlacek */ @NbBundle.Messages({ "CAP_ProfileStartup=Profile Startup", "MSG_AnotherSessionRunning=Another profiling session in progress.

Please finish profiling of {0}
before starting a new profiling session." }) final class StartupProfiler { private static StartupProfiler sharedInstance; private StartupConfigurator configurator; static synchronized StartupProfiler sharedInstance() { if (sharedInstance == null) sharedInstance = new StartupProfiler(); return sharedInstance; } void profileStartup() { SwingUtilities.invokeLater(new Runnable() { public void run() { String profiledApp = ProfilerSupport.getInstance().getProfiledApplicationName(); if (profiledApp != null) { Dialogs.show(Dialogs.warning(Bundle.CAP_ProfileStartup(), Bundle.MSG_AnotherSessionRunning(profiledApp))); return; } if (configurator == null) configurator = new StartupConfigurator(); Dialog d = Dialogs.dialog(Bundle.CAP_ProfileStartup(), configurator.getUI()); d.pack(); Dialogs.show(d); if (configurator.accepted()) attachToProcess(); } }); } private void attachToProcess() { final int port = configurator.getPort(); final String java = configurator.getJavaPlatform(); final int architecture = configurator.getArchitecture(); final ProfilerSettingsSupport settings = configurator.getSettings(); final ProfilerPreset preset = configurator.getPreset(); RequestProcessor.getDefault().post(new Runnable() { public void run() { ProfilerSupport.getInstance().profileProcessStartup(java, architecture, port, settings, preset); } }); } } ================================================ FILE: plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/StartupProfilerAction.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.profiler.startup; import org.graalvm.visualvm.profiler.ProfilerSupport; import java.awt.Image; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; /** * * @author Jiri Sedlacek */ @NbBundle.Messages({ "NAME_ProfileStartup=Prof&ile Startup", "DESC_ProfileStartup=Start new process and profile its startup" }) final class StartupProfilerAction extends AbstractAction { private static final String ICON_PATH = "org/graalvm/visualvm/profiler/startup/resources/profiler.png"; // NOI18N static final Image ICON = ImageUtilities.loadImage(ICON_PATH); private static StartupProfilerAction menuInstance; private static StartupProfilerAction toolbarAction; static synchronized StartupProfilerAction toolbarInstance() { if (menuInstance == null) { menuInstance = new StartupProfilerAction(); menuInstance.putValue(SMALL_ICON, new ImageIcon(ICON)); menuInstance.putValue("iconBase", ICON_PATH); // NOI18N } return menuInstance; } static synchronized StartupProfilerAction menuInstance() { if (toolbarAction == null) { toolbarAction = new StartupProfilerAction(); } return toolbarAction; } public void actionPerformed(ActionEvent actionEvent) { StartupProfiler.sharedInstance().profileStartup(); } public boolean isEnabled() { return ProfilerSupport.getInstance().hasSupportedJavaPlatforms(); } private StartupProfilerAction() { putValue(Action.NAME, Bundle.NAME_ProfileStartup()); putValue(Action.SHORT_DESCRIPTION, Bundle.DESC_ProfileStartup()); } } ================================================ FILE: plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/resources/layer.xml ================================================ ================================================ FILE: plugins/systray/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.systray. ================================================ FILE: plugins/systray/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.modules.systray/2 OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/systray/Bundle.properties OpenIDE-Module-Specification-Version: 2.0 OpenIDE-Module-Install: org/graalvm/visualvm/modules/systray/Install.class ================================================ FILE: plugins/systray/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/systray/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=2f82a819 build.xml.script.CRC32=a7b0ec32 build.xml.stylesheet.CRC32=a56c6a5b@2.73 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=2f82a819 nbproject/build-impl.xml.script.CRC32=01ff4d5c nbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73 ================================================ FILE: plugins/systray/nbproject/project.properties ================================================ javac.source=1.5 javac.compilerargs=-Xlint -Xlint:-serial license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Jiri Sedlacek module.javadoc.packages=org.graalvm.visualvm.modules.systray.* ================================================ FILE: plugins/systray/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.systray org.openide.dialogs 7.5.1 org.openide.modules 7.3.1 org.openide.util 9.8 org.openide.util.ui 9.8 org.openide.windows 6.18.1 ================================================ FILE: plugins/systray/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/systray/src/org/graalvm/visualvm/modules/systray/Bundle.properties ================================================ OpenIDE-Module-Display-Category=Tools OpenIDE-Module-Long-Description=\ Allows to minimize/restore running VisualVM instance into/from system tray. \ Not supported on macOS (does nothing). OpenIDE-Module-Name=SysTray OpenIDE-Module-Short-Description=Allows to minimize running VisualVM instance into system tray. ================================================ FILE: plugins/systray/src/org/graalvm/visualvm/modules/systray/Install.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.systray; import org.openide.modules.ModuleInstall; import org.openide.util.Utilities; import org.openide.windows.WindowManager; /** * * @author Jiri Sedlacek */ public class Install extends ModuleInstall { public void restored() { // SysTray isn't supported for Mac if (Utilities.isMac()) return; WindowManager.getDefault().invokeWhenUIReady(new Runnable() { public void run() { SysTray.getInstance().initialize(); } }); } public void uninstalled() { // SysTray isn't supported for Mac if (Utilities.isMac()) return; SysTray.getInstance().uninitialize(); } } ================================================ FILE: plugins/systray/src/org/graalvm/visualvm/modules/systray/SysTray.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.systray; import java.awt.AWTException; import java.awt.CheckboxMenuItem; import java.awt.Dialog; import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; import java.awt.Image; import java.awt.MenuItem; import java.awt.PopupMenu; import java.awt.SystemTray; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowEvent; import java.awt.event.WindowStateListener; import javax.swing.SwingUtilities; import javax.swing.UIManager; import org.openide.DialogDisplayer; import org.openide.LifecycleManager; import org.openide.NotifyDescriptor; import org.openide.util.Exceptions; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; import org.openide.util.Utilities; import org.openide.windows.WindowManager; /** * * @author Jiri Sedlacek */ @NbBundle.Messages({ "SysTray_NotSupportedUninstall=VisualVM tray icon not supported.

Your system can't display VisualVM tray icon.
Please uninstall the plugin.", "SysTray_Show=Show", "SysTray_Hide=Hide", "SysTray_AlwaysOnTop=Always on top", "SysTray_HideWhenMinimized=Hide when minimized", "SysTray_NoTrayicon=No trayicon when showing", "SysTray_Exit=Exit", "SysTray_Settings=Settings", "SysTray_ModalDialog=Modal dialog in the way.

Please close all modal dialogs before hiding VisualVM." }) class SysTray { private static SysTray INSTANCE; private TrayIcon trayIcon; private Frame mainWindow; private WindowStateListener mainWindowListener; private PopupMenu trayPopup; private MenuItem showHideItem; private MenuItem exitItem; private CheckboxMenuItem onTopItem; private CheckboxMenuItem hideMinimizedItem; private CheckboxMenuItem hideTrayIconItem; private int lastWindowState; private boolean hideWhenMinimized; private boolean hideTrayIcon; private boolean workaround; static synchronized SysTray getInstance() { if (INSTANCE == null) INSTANCE = new SysTray(); return INSTANCE; } synchronized void initialize() { if (SystemTray.isSupported()) { mainWindow = WindowManager.getDefault().getMainWindow(); mainWindowListener = new MainWindowListener(); lastWindowState = mainWindow.getExtendedState(); loadSettings(); if (!hideTrayIcon) showTrayIcon(); mainWindow.addWindowStateListener(mainWindowListener); } } synchronized void uninitialize() { if (trayIcon != null) hideTrayIcon(); if (mainWindow != null && mainWindowListener != null) { mainWindow.removeWindowStateListener(mainWindowListener); mainWindow = null; } } private void loadSettings() { SysTrayPreferences preferences = SysTrayPreferences.getInstance(); hideWhenMinimized = preferences.getHideWhenMinimized(); hideTrayIcon = preferences.getHideTrayIcon(); } private void showTrayIcon() { try { SystemTray tray = SystemTray.getSystemTray(); if (tray != null) { trayIcon = createTrayIcon(); if (trayIcon != null) { try { tray.add(trayIcon); } catch (AWTException e) { trayIcon = null; DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message( Bundle.SysTray_NotSupportedUninstall(), NotifyDescriptor.ERROR_MESSAGE)); System.err.println("Exception showing tray icon: " + e); // NOI18N } catch (Exception e) { trayIcon = null; Exceptions.printStackTrace(e); } } } } catch (Exception e) { Exceptions.printStackTrace(e); } } private void hideTrayIcon() { SystemTray tray = SystemTray.getSystemTray(); if (tray != null) { try { tray.remove(trayIcon); } catch (Exception e) { Exceptions.printStackTrace(e); } } trayIcon = null; } private TrayIcon createTrayIcon() { Image image = createTrayImage(); String tooltip = createTrayTooltip(); trayPopup = createTrayPopup(); TrayIcon icon = new TrayIcon(image, tooltip, trayPopup); icon.setImageAutoSize(true); icon.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { if (trayPopup.isEnabled()) toggleWindowVisibility(); } }); } }); return icon; } private String createTrayTooltip() { return mainWindow.getTitle(); } private Image createTrayImage() { Dimension iconDimension = SystemTray.getSystemTray().getTrayIconSize(); int iconWidth = iconDimension.width; int iconHeight = iconDimension.height; if (iconWidth <= 16 && iconHeight <= 16) return ImageUtilities.loadImage("org/graalvm/visualvm/modules/systray/resources/icon16.png"); // NOI18N if (iconWidth <= 32 && iconHeight <= 32) return ImageUtilities.loadImage("org/graalvm/visualvm/modules/systray/resources/icon32.png"); // NOI18N return ImageUtilities.loadImage("org/graalvm/visualvm/modules/systray/resources/icon48.png"); // NOI18N } private PopupMenu createTrayPopup() { // "Show / Hide" menu item showHideItem = new MenuItem(mainWindow.isVisible() ? Bundle.SysTray_Hide() : Bundle.SysTray_Show()); showHideItem.setFont(UIManager.getFont("MenuItem.font").deriveFont(Font.BOLD)); // NOI18N showHideItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { toggleWindowVisibility(); } }); } }); // "Always on top" menu item if (Toolkit.getDefaultToolkit().isAlwaysOnTopSupported() && mainWindow.isAlwaysOnTopSupported()) { onTopItem = new CheckboxMenuItem(Bundle.SysTray_AlwaysOnTop(), SysTrayPreferences.getInstance().getAlwaysOnTop()); onTopItem.setFont(UIManager.getFont("MenuItem.font")); // NOI18N onTopItem.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { toggleAlwaysOnTop(); } }); } }); toggleAlwaysOnTop(); // Sets initial state } // "Hide when minimized" menu item hideMinimizedItem = new CheckboxMenuItem(Bundle.SysTray_HideWhenMinimized(), hideWhenMinimized); hideMinimizedItem.setFont(UIManager.getFont("MenuItem.font")); // NOI18N hideMinimizedItem.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { toggleHideWhenMinimized(); } }); } }); // "No trayicon when showing" menu item hideTrayIconItem = new CheckboxMenuItem(Bundle.SysTray_NoTrayicon(), hideTrayIcon); hideTrayIconItem.setFont(UIManager.getFont("MenuItem.font")); // NOI18N hideTrayIconItem.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { toggleNoShowingIcon(); } }); } }); // "Exit" menu item exitItem = new MenuItem(Bundle.SysTray_Exit()); exitItem.setFont(UIManager.getFont("MenuItem.font")); // NOI18N exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { LifecycleManager.getDefault().exit(); } }); } }); // "Settings" submenu PopupMenu settingsItem = new PopupMenu(Bundle.SysTray_Settings()); settingsItem.setFont(UIManager.getFont("MenuItem.font")); // NOI18N if (onTopItem != null) settingsItem.add(onTopItem); settingsItem.add(hideMinimizedItem); settingsItem.add(hideTrayIconItem); PopupMenu popupMenu = new PopupMenu(); popupMenu.add(showHideItem); popupMenu.add(settingsItem); popupMenu.addSeparator(); popupMenu.add(exitItem); return popupMenu; } private void toggleWindowVisibility() { if (mainWindow.isVisible()) hideWindow(); // May not hide window when modal dialog(s) in the way else showWindow(); } private void hideWindow() { Window[] windows = mainWindow.getOwnedWindows(); for (Window window : windows) { if (window.isVisible() && window instanceof Dialog) if (((Dialog)window).isModal()) { trayPopup.setEnabled(false); DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( Bundle.SysTray_ModalDialog(), NotifyDescriptor.WARNING_MESSAGE)); trayPopup.setEnabled(true); return; } } mainWindow.setVisible(false); if (!Utilities.isWindows() && (mainWindow.getExtendedState() & Frame.ICONIFIED) != 0) { workaround = true; } if (showHideItem != null) showHideItem.setLabel(Bundle.SysTray_Show()); } private void showWindow() { mainWindow.setVisible(true); mainWindow.setExtendedState(lastWindowState); showHideItem.setLabel(Bundle.SysTray_Hide()); mainWindow.toFront(); } private void toggleAlwaysOnTop() { mainWindow.setAlwaysOnTop(onTopItem.getState()); SysTrayPreferences.getInstance().setAlwaysOnTop(onTopItem.getState()); } private void toggleHideWhenMinimized() { hideWhenMinimized = hideMinimizedItem.getState(); if (hideWhenMinimized && (mainWindow.getExtendedState() & Frame.ICONIFIED) != 0) hideWindow(); // May not hide window when modal dialog(s) in the way SysTrayPreferences.getInstance().setHideWhenMinimized(hideWhenMinimized); } private void toggleNoShowingIcon() { hideTrayIcon = hideTrayIconItem.getState(); int windowState = mainWindow.getExtendedState(); if ((windowState & Frame.ICONIFIED) != 0) { if (hideTrayIcon && trayIcon == null) showTrayIcon(); } else { if (hideTrayIcon && trayIcon != null) hideTrayIcon(); } SysTrayPreferences.getInstance().setHideTrayIcon(hideTrayIcon); } private SysTray() {} private class MainWindowListener implements WindowStateListener { public void windowStateChanged(WindowEvent e) { int windowState = e.getNewState(); if ((windowState & Frame.ICONIFIED) != 0) { if (workaround) { workaround = false; mainWindow.setExtendedState(lastWindowState); } else { workaround = false; if (hideWhenMinimized || hideTrayIcon) hideWindow(); // May not hide window when modal dialog(s) in the way if (!mainWindow.isVisible() && hideTrayIcon && trayIcon == null) showTrayIcon(); } } else { lastWindowState = windowState; if (hideTrayIcon && trayIcon != null) hideTrayIcon(); } } } } ================================================ FILE: plugins/systray/src/org/graalvm/visualvm/modules/systray/SysTrayPreferences.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.systray; import java.util.prefs.Preferences; import org.openide.util.NbPreferences; /** * * @author Jiri Sedlacek */ final class SysTrayPreferences { private static SysTrayPreferences INSTANCE = new SysTrayPreferences(); private static final String KEY_ALWAYS_ON_TOP = "AlwaysOnTop"; // NOI18N private static final String KEY_HIDE_WHEN_MINIMIZED = "HideWhenMinimized"; // NOI18N private static final String KEY_HIDE_TRAY_ICON = "HideTrayIcon"; // NOI18N private final static boolean ALWAYS_ON_TOP_DEFAULT = false; private final static boolean HIDE_WHEN_MINIMIZED_DEFAULT = true; private final static boolean HIDE_TRAY_ICON_DEFAULT = false; private final Preferences prefs; static synchronized SysTrayPreferences getInstance() { if (INSTANCE == null) INSTANCE = new SysTrayPreferences(); return INSTANCE; } void setAlwaysOnTop(boolean alwaysOnTop) { synchronized(prefs) { prefs.putBoolean(KEY_ALWAYS_ON_TOP, alwaysOnTop); } } boolean getAlwaysOnTop() { synchronized(prefs) { return prefs.getBoolean(KEY_ALWAYS_ON_TOP, ALWAYS_ON_TOP_DEFAULT); } } void setHideWhenMinimized(boolean hideWhenMinimized) { synchronized(prefs) { prefs.putBoolean(KEY_HIDE_WHEN_MINIMIZED, hideWhenMinimized); } } boolean getHideWhenMinimized() { synchronized(prefs) { return prefs.getBoolean(KEY_HIDE_WHEN_MINIMIZED, HIDE_WHEN_MINIMIZED_DEFAULT); } } void setHideTrayIcon(boolean hideTrayIcon) { synchronized(prefs) { prefs.putBoolean(KEY_HIDE_TRAY_ICON, hideTrayIcon); } } boolean getHideTrayIcon() { synchronized(prefs) { return prefs.getBoolean(KEY_HIDE_TRAY_ICON, HIDE_TRAY_ICON_DEFAULT); } } private SysTrayPreferences() { prefs = NbPreferences.forModule(SysTrayPreferences.class); } } ================================================ FILE: plugins/threadinspect/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.modules.threadinspect. ================================================ FILE: plugins/threadinspect/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module: org.graalvm.visualvm.modules.threadinspect/2 OpenIDE-Module-Install: org/graalvm/visualvm/modules/threadinspect/Installer.class OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/threadinspect/Bundle.properties OpenIDE-Module-Specification-Version: 2.0 ================================================ FILE: plugins/threadinspect/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: plugins/threadinspect/nbproject/project.properties ================================================ javac.source=1.5 javac.compilerargs=-Xlint -Xlint:-serial license.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io nbm.module.author=Jiri Sedlacek nbm.needs.restart=true module.javadoc.packages=org.graalvm.visualvm.modules.threadinspect.* ================================================ FILE: plugins/threadinspect/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.modules.threadinspect org.graalvm.visualvm.application 2 2.0 org.graalvm.visualvm.application.views 2 2.0 org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.tools 2 2.0 org.graalvm.visualvm.uisupport 2 2.0 org.openide.modules 7.13.1 org.openide.util 9.8 org.openide.util.ui 9.8 ================================================ FILE: plugins/threadinspect/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: plugins/threadinspect/src/org/graalvm/visualvm/modules/threadinspect/Bundle.properties ================================================ # # Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Tools OpenIDE-Module-Long-Description=\ Threads Inspector adds a new section to the Threads tab showing stack traces for the selected live threads. OpenIDE-Module-Name=Threads Inspector OpenIDE-Module-Short-Description=Threads Inspector plugin for VisualVM ================================================ FILE: plugins/threadinspect/src/org/graalvm/visualvm/modules/threadinspect/Engine.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.threadinspect; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.options.GlobalPreferences; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; import org.graalvm.visualvm.tools.jmx.JvmMXBeans; import org.graalvm.visualvm.tools.jmx.JvmMXBeansFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author Jiri Sedlacek * @author Tomas Hurka */ final class Engine { private static final Logger LOGGER = Logger.getLogger(Engine.class.getName()); private JmxModel jmxModel; private ThreadMXBean threadBean; static Engine getEngine(Application application) { try { JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application); if (jmxModel != null && jmxModel.getConnectionState() == ConnectionState.CONNECTED) { JvmMXBeans mxbeans = JvmMXBeansFactory.getJvmMXBeans(jmxModel, GlobalPreferences.sharedInstance().getThreadsPoll() * 1000); if (jmxModel != null) { ThreadMXBean tbean = mxbeans.getThreadMXBean(); if (tbean != null) { return new Engine(jmxModel,tbean); } } } } catch (Throwable t) { LOGGER.log(Level.INFO, "Problem resolving ThreadMXBean", t); // NOI18N } return null; } Engine(JmxModel model, ThreadMXBean tbean) { jmxModel = model; threadBean = tbean; } List getThreadInfos() { List tinfosList = null; try { long[] threadIds = threadBean.getAllThreadIds(); ThreadInfo[] threadInfos = threadBean.getThreadInfo(threadIds); tinfosList = new ArrayList(threadInfos.length); for (ThreadInfo tinfo : threadInfos) if (tinfo != null && tinfo.getThreadName() != null) tinfosList.add(tinfo); Collections.sort(tinfosList, new Comparator() { public int compare(ThreadInfo ti1, ThreadInfo ti2) { return ti1.getThreadName().compareTo(ti2.getThreadName()); } }); } catch (Throwable t) { LOGGER.log(Level.INFO, "Problem resolving ThreadInfos", t); // NOI18N } return tinfosList; } String getStackTraces(List threadIdsL) { long[] threadIds = new long[threadIdsL.size()]; for (int i = 0; i < threadIds.length; i++) threadIds[i] = threadIdsL.get(i); String stackTraces = jmxModel.takeThreadDump(threadIds); return "
" + transform(htmlize(stackTraces)) + "
"; // NOI18N } private static String htmlize(String value) { return value.replace("&", "&").replace("<", "<"); // NOI18N } private static String transform(String value) { StringBuilder sb = new StringBuilder(); String[] result = value.split("\\n"); // NOI18N for (int i = 0; i < result.length; i++) { String line = result[i]; if (!line.isEmpty() && !Character.isWhitespace(line.charAt(0))) { sb.append(""); // NOI18N sb.append(line); sb.append("
"); // NOI18N } else { sb.append(line); sb.append("
"); // NOI18N } } return sb.toString(); } } ================================================ FILE: plugins/threadinspect/src/org/graalvm/visualvm/modules/threadinspect/Installer.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.threadinspect; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.views.ApplicationViewsSupport; import org.graalvm.visualvm.core.ui.DataSourceViewPlugin; import org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.core.ui.components.DataViewComponent.DetailsView; import org.openide.modules.ModuleInstall; /** * * @author Jiri Sedlacek */ final class Installer extends ModuleInstall { public void restored() { ApplicationViewsSupport.sharedInstance().getThreadsView(). registerPluginProvider(new ThreadsViewPluginProvider()); } private static class ThreadsViewPluginProvider extends DataSourceViewPluginProvider { protected boolean supportsPluginFor(Application application) { return true; } protected DataSourceViewPlugin createPlugin(Application application) { return new ThreadInspectorViewPlugin(application); } } private static class ThreadInspectorViewPlugin extends DataSourceViewPlugin { public DetailsView createView(int location) { switch (location) { case DataViewComponent.BOTTOM_LEFT: return new DataViewComponent.DetailsView("Threads inspector", null, 10, new ThreadsInspector((Application) getDataSource()), null); default: return null; } } ThreadInspectorViewPlugin(Application application) { super(application); } } } ================================================ FILE: plugins/threadinspect/src/org/graalvm/visualvm/modules/threadinspect/JExtendedSplitPane.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.threadinspect; import java.awt.Component; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import javax.swing.JSplitPane; import javax.swing.plaf.basic.BasicSplitPaneUI; /** * Copy of org.graalvm.visualvm.core.ui.components.JExtendedSplitPane. * * @author Jiri Sedlacek */ class JExtendedSplitPane extends JSplitPane { private HierarchyListener leftComponentListener; private HierarchyListener rightComponentListener; private double dividerLocation; private int customDividerSize; private double requestedDividerLocation = -1; public JExtendedSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent) { this(newOrientation, false, newLeftComponent, newRightComponent); } public JExtendedSplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent, Component newRightComponent) { super(newOrientation, newContinuousLayout, newLeftComponent, newRightComponent); updateVisibility(); if (!newLeftComponent.isVisible()) computeDividerLocationWhenInitiallyHidden(newLeftComponent); if (!newRightComponent.isVisible()) computeDividerLocationWhenInitiallyHidden(newRightComponent); } public void setDividerSize(int newSize) { super.setDividerSize(newSize); customDividerSize = newSize; } public void setDividerLocation(double requestedDividerLocation) { Component divider = getDivider(); if (isVisible() && divider.isVisible()) { // SplitPane fully visible super.setDividerLocation(requestedDividerLocation); dividerLocation = requestedDividerLocation; } else if (isVisible()) { // Divider not visible, will be updated in updateVisibility() dividerLocation = requestedDividerLocation; } else if (!isVisible()) { // SplitPane not visible, dividerLocation will be set on first reasonable getSize() this.requestedDividerLocation = requestedDividerLocation; } } public void setLeftComponent(Component newLeftComponent) { if (leftComponent != null) { leftComponent.removeHierarchyListener(leftComponentListener); leftComponentListener = null; } super.setLeftComponent(newLeftComponent); if (getLeftComponent() != null) { leftComponentListener = new VisibilityListener(newLeftComponent); newLeftComponent.addHierarchyListener(leftComponentListener); } updateVisibility(); } public void setRightComponent(Component newRightComponent) { if (rightComponent != null) { rightComponent.removeHierarchyListener(rightComponentListener); rightComponentListener = null; } super.setRightComponent(newRightComponent); if (getRightComponent() != null) { rightComponentListener = new VisibilityListener(newRightComponent); newRightComponent.addHierarchyListener(rightComponentListener); } updateVisibility(); } public void reshape(int x, int y, int width, int height) { super.reshape(x, y, width, height); if (width > 0 && height > 0 && requestedDividerLocation != -1) { super.setDividerLocation(requestedDividerLocation); dividerLocation = requestedDividerLocation; // SplitPaneUI.paint() needs to be invoked here to set the // BasicSplitPaneUI.painted flag to enable resizing the divider // even if the component hasn't been shown yet. ((BasicSplitPaneUI)getUI()).paint(getGraphics(), this); requestedDividerLocation = -1; } } private Component getDivider() { if (ui == null) return null; return ((BasicSplitPaneUI)ui).getDivider(); } private void computeDividerLocationWhenHidden(Component hiddenComponent) { if (leftComponent.isVisible() || rightComponent.isVisible()) { boolean horiz = getOrientation() == JSplitPane.HORIZONTAL_SPLIT; double size = horiz ? getSize().getWidth() : getSize().getHeight(); double csize = horiz ? hiddenComponent.getSize().getWidth() : hiddenComponent.getSize().getHeight(); computeDividerLocation(hiddenComponent, size, csize); } } private void computeDividerLocationWhenInitiallyHidden(Component hiddenComponent) { if (leftComponent.isVisible() || rightComponent.isVisible()) { boolean horiz = getOrientation() == JSplitPane.HORIZONTAL_SPLIT; double size = horiz ? getPreferredSize().getWidth() : getPreferredSize().getHeight(); double csize = horiz ? hiddenComponent.getPreferredSize().getWidth() : hiddenComponent.getPreferredSize().getHeight(); computeDividerLocation(hiddenComponent, size, csize); } } private void computeDividerLocation(Component hiddenComponent, double size, double csize) { if (hiddenComponent == leftComponent) { dividerLocation = csize / (size - customDividerSize); } else { dividerLocation = (size - customDividerSize - csize) / (size - customDividerSize); } } private void updateVisibility() { Component divider = getDivider(); // null UI, not yet set if (divider == null) return; if (leftComponent == null || rightComponent == null) return; boolean leftVisible = leftComponent.isVisible(); boolean rightVisible = rightComponent.isVisible(); if (leftVisible && rightVisible) { if (!divider.isVisible()) { JExtendedSplitPane.super.setDividerSize(customDividerSize); divider.setVisible(true); setDividerLocation(dividerLocation); } if (!isVisible()) setVisible(true); } else if (!leftVisible && !rightVisible) { if (isVisible()) setVisible(false); } else { if (divider.isVisible()) { JExtendedSplitPane.super.setDividerSize(0); divider.setVisible(false); setDividerLocation(0); } if (!isVisible()) setVisible(true); } if (getParent() != null) getParent().doLayout(); } private class VisibilityListener implements HierarchyListener { private boolean wasVisible; private final Component c; VisibilityListener(Component c) { this.c = c; wasVisible = c.isVisible(); } public void hierarchyChanged(HierarchyEvent e) { if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) { boolean visible = c.isVisible(); if (wasVisible == visible) return; wasVisible = visible; if (visible) componentShown(); else componentHidden(c); } } private void componentHidden(Component c) { computeDividerLocationWhenHidden(c); // Make sure the component is visible when shown if ((dividerLocation <= 0) || (dividerLocation >= 1)) dividerLocation = 0.5; updateVisibility(); } private void componentShown() { updateVisibility(); } } } ================================================ FILE: plugins/threadinspect/src/org/graalvm/visualvm/modules/threadinspect/ThreadsInspector.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.modules.threadinspect; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.core.datasupport.DataRemovedListener; import org.graalvm.visualvm.core.datasupport.Stateful; import org.graalvm.visualvm.core.ui.components.ScrollableContainer; import org.graalvm.visualvm.uisupport.HTMLTextArea; import org.graalvm.visualvm.uisupport.UISupport; import org.graalvm.visualvm.uisupport.VerticalLayout; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.KeyboardFocusManager; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.management.ThreadInfo; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.plaf.basic.BasicSplitPaneDivider; import javax.swing.plaf.basic.BasicSplitPaneUI; import org.openide.util.RequestProcessor; import org.openide.util.WeakListeners; /** * * @author Jiri Sedlacek */ final class ThreadsInspector extends JPanel implements DataRemovedListener, PropertyChangeListener { private static final Color BACKGROUND; private static final Color ITEM_HIGHLIGHT; private static final Color SPLITTER_HIGHLIGHT; private static final int SPACING = getPresenterSpacing(); private static final String EMPTY = "E"; // NOI18N private static final String DATA = "D"; // NOI18N static { BACKGROUND = UISupport.getDefaultBackground(); int darkerR = BACKGROUND.getRed() - 11; if (darkerR < 0) darkerR += 26; int darkerG = BACKGROUND.getGreen() - 11; if (darkerG < 0) darkerG += 26; int darkerB = BACKGROUND.getBlue() - 11; if (darkerB < 0) darkerB += 26; ITEM_HIGHLIGHT = new Color(darkerR, darkerG, darkerB); darkerR = BACKGROUND.getRed() - 20; if (darkerR < 0) darkerR += 40; darkerG = BACKGROUND.getGreen() - 20; if (darkerG < 0) darkerG += 40; darkerB = BACKGROUND.getBlue() - 20; if (darkerB < 0) darkerB += 40; SPLITTER_HIGHLIGHT = new Color(darkerR, darkerG, darkerB); } private final Application application; private Engine threadEngine; private Set selectedThreads; private JButton refreshButton; private JPanel threadsContainer; private JPanel threadsContainerContainer; private CardLayout detailsLayout; private JPanel detailsContainer; private HTMLTextArea threadsDetails; private Long focusedThreadId = Long.MIN_VALUE; private boolean internalDetailsChange; public ThreadsInspector(Application application) { this.application = application; initUI(); showProgress(); initThreads(); } public void dataRemoved(Application application) { disableUI(); } public void propertyChange(PropertyChangeEvent evt) { disableUI(); } private void initUI() { setOpaque(false); setLayout(new BorderLayout(0, 0)); } private void initThreads() { RequestProcessor.getDefault().post(new Runnable() { public void run() { if (application.getState() != Stateful.STATE_AVAILABLE) { showError("Application finished"); } else { threadEngine = Engine.getEngine(application); if (threadEngine == null) { showError("Cannot access threads using JMX."); } else { application.notifyWhenRemoved(ThreadsInspector.this); application.addPropertyChangeListener(Stateful.PROPERTY_STATE, WeakListeners.propertyChange(ThreadsInspector.this, application)); SwingUtilities.invokeLater(new Runnable() { public void run() { createUI(); refreshData(); } }); } } } }); } private void refreshData() { if (!refreshButton.isEnabled()) return; if (application.getState() != Stateful.STATE_AVAILABLE) { disableUI(); return; } RequestProcessor.getDefault().post(new Runnable() { public void run() { final List tinfs = threadEngine.getThreadInfos(); if (tinfs == null) { disableUI(); return; } if (selectedThreads == null) selectedThreads = new HashSet(); SwingUtilities.invokeLater(new Runnable() { public void run() { threadsContainer.removeAll(); List toDisplay = new ArrayList(); Set selectedZombies = new HashSet(selectedThreads); for (ThreadInfo tinfo : tinfs) { String name = tinfo.getThreadName(); final long id = tinfo.getThreadId(); selectedZombies.remove(id); final JCheckBox cb = new JCheckBox(name, selectedThreads. contains(id)) { protected void fireActionPerformed(ActionEvent e) { focusedThreadId = id; if (!selectedThreads.remove(id)) selectedThreads.add(id); refreshData(); } public Dimension getPreferredSize() { Dimension size = super.getPreferredSize(); size.height += SPACING; return size; } }; cb.setOpaque(false); JPanel cbp = new JPanel(null) { public Dimension getPreferredSize() { Dimension size = cb.getPreferredSize(); size.width += 8; return size; } public void doLayout() { cb.setBounds(4, 0, getWidth() - 8, getHeight()); } public void setEnabled(boolean enabled) { super.setEnabled(enabled); for (Component c : getComponents()) c.setEnabled(enabled); } }; cbp.setOpaque(true); cbp.setBackground(threadsContainer.getComponentCount() % 2 == 0 ? BACKGROUND : ITEM_HIGHLIGHT); cbp.add(cb, BorderLayout.CENTER); threadsContainer.add(cbp); if (focusedThreadId == id) { cb.requestFocusInWindow(); focusedThreadId = Long.MIN_VALUE; } if (cb.isSelected()) toDisplay.add(id); } selectedThreads.removeAll(selectedZombies); // Workaround for JDK7 bug, JScrollPane doesn't layout // correctly when in a not-selected JTabPane and updated // lazily. Overriding isValidateRoot() on JScrollPane // to return false also works around this problem. threadsContainerContainer.invalidate(); threadsContainerContainer.validate(); if (!toDisplay.isEmpty()) displayStackTraces(toDisplay); else showDetails(""); // NOI18N } }); } }); } private void displayStackTraces(final List toDisplay) { RequestProcessor.getDefault().post(new Runnable() { public void run() { final String text = threadEngine.getStackTraces(toDisplay); if (text != null) SwingUtilities.invokeLater(new Runnable() { public void run() { showDetails(text); } }); } }); } private void disableUI() { SwingUtilities.invokeLater(new Runnable() { public void run() { refreshButton.setEnabled(false); threadsContainer.setEnabled(false); Component focused = KeyboardFocusManager. getCurrentKeyboardFocusManager().getFocusOwner(); if (focused != null && focused.getParent() == threadsContainer) threadsDetails.requestFocusInWindow(); } }); } private void showProgress() { JLabel waitLabel = new JLabel("Resolving threads...", SwingConstants.CENTER); waitLabel.setEnabled(false); add(waitLabel, BorderLayout.CENTER); } private void showError(final String error) { SwingUtilities.invokeLater(new Runnable() { public void run() { removeAll(); add(new HTMLTextArea("Unable to inspect threads.
" + error), BorderLayout.CENTER); revalidate(); repaint(); } }); } private void showDetails(String text) { internalDetailsChange = true; threadsDetails.setText(text); if (text.isEmpty()) detailsLayout.show(detailsContainer, EMPTY); else detailsLayout.show(detailsContainer, DATA); } private void createUI() { JLabel hintLabel = new JLabel("", // NOI18N "ExternalSourcesViewer_Name=External Viewer", // NOI18N "ExternalSourcesViewer_Description=custom command to launch an external viewer", // NOI18N "ExternalSourcesViewer_NotConfiguredCaption=Go To Source", // NOI18N "ExternalSourcesViewer_NotConfigured=
Sources viewer has not been configured yet.

Use Options | Sources | Viewer to define the external IDE or editor to open the sources.

Customize a predefined template from the popup list or define a custom command using
the available parameters to launch the external sources viewer.

Alternatively choose to use a viewer registered in the OS (preselecting line not supported).", // NOI18N "# {0} - error message", "ExternalSourcesViewer_CommandFailed=Failed to open source in external viewer.\n\n{0}", // NOI18N "ExternalSourcesViewer_CommandLabel=&Command:", // NOI18N "ExternalSourcesViewer_RootsDialogCaption=Select File Or Directory", // NOI18N "ExternalSourcesViewer_RootsDialogButton=Select", // NOI18N "ExternalSourcesViewer_OpenRootsDialogToolTip=Insert file or directory", // NOI18N "ExternalSourcesViewer_InsertCommandToolTip=Insert predefined command or parameter" // NOI18N }) @ServiceProvider(service=SourcesViewer.class, position = 300) public final class ExternalSourcesViewer extends SourcesViewer { private static final Logger LOGGER = Logger.getLogger(ExternalSourcesViewer.class.getName()); public static final String ID = "ExternalSourcesViewer"; // NOI18N private static final String PROP_COMMAND = "prop_ExternalSourcesViewer_command"; // NOI18N private static final String DEFAULT_COMMAND = Bundle.ExternalSourcesViewer_CommandHint(); private static enum IdePreset { NETBEANS("NetBeans", "netbeans " + SourceHandle.Feature.FILE.getCode() + ":" + SourceHandle.Feature.LINE.getCode()), // NOI18N ECLIPSE("Eclipse", "eclipse " + SourceHandle.Feature.FILE.getCode() + ":" + SourceHandle.Feature.LINE.getCode()), // NOI18N IDEA("IntelliJ IDEA", "idea --line " + SourceHandle.Feature.LINE.getCode() + " --column " + SourceHandle.Feature.COLUMN.getCode() + " " + SourceHandle.Feature.FILE.getCode()), // NOI18N VSCODE("Visual Studio Code", "code -g " + SourceHandle.Feature.FILE.getCode() + ":" + SourceHandle.Feature.LINE.getCode()), // NOI18N XCODE("Xcode", "open -a Xcode " + SourceHandle.Feature.FILE.getCode()); // NOI18N private final String name; private final String command; IdePreset(String name, String command) { this.name = name; this.command = command; } String getName() { return name; } String getCommand() { return command; } @Override public String toString() { return getName(); } static IdePreset[] sorted() { IdePreset[] commands = values(); Arrays.sort(commands, new Comparator() { @Override public int compare(IdePreset c1, IdePreset c2) { return c1.name.compareTo(c2.name); } }); return commands; } } private static enum ToolPreset { NOTEPAD("Notepad", "notepad.exe " + SourceHandle.Feature.FILE.getCode()), // NOI18N NOTEPADPP("Notepad++", "notepad++ -p" + SourceHandle.Feature.OFFSET.getCode() + " " + SourceHandle.Feature.FILE.getCode()), // NOI18N GEDIT("Gedit", "gedit +" + SourceHandle.Feature.LINE.getCode() + " " + SourceHandle.Feature.FILE.getCode()), // NOI18N EMACS("Emacs", "emacs +" + SourceHandle.Feature.LINE.getCode() + ":" + SourceHandle.Feature.COLUMN.getCode() + " " + SourceHandle.Feature.FILE.getCode()), // NOI18N KATE("Kate", "kate -l " + SourceHandle.Feature.LINE.getCode() + " -c " + SourceHandle.Feature.COLUMN.getCode() + " " + SourceHandle.Feature.FILE.getCode()); // NOI18N private final String name; private final String command; ToolPreset(String name, String command) { this.name = name; this.command = command; } String getName() { return name; } String getCommand() { return command; } @Override public String toString() { return getName(); } static ToolPreset[] sorted() { ToolPreset[] commands = values(); Arrays.sort(commands, new Comparator() { @Override public int compare(ToolPreset c1, ToolPreset c2) { return c1.name.compareTo(c2.name); } }); return commands; } } private final String forcedCommand; private JPanel settingsPanel; private JTextField commandField; public ExternalSourcesViewer() { this(null); } public ExternalSourcesViewer(String forcedCommand) { super(ID, Bundle.ExternalSourcesViewer_Name(), Bundle.ExternalSourcesViewer_Description()); this.forcedCommand = forcedCommand; } @Override public boolean open(SourceHandle handle) { String command = getCommand(); if (command.isEmpty() || command.equals(DEFAULT_COMMAND)) configureCommand(); else executeCommand(handle, command); return true; } @Override public void loadSettings() { if (forcedCommand == null && settingsPanel != null) commandField.setText(getCommand()); } @Override public void saveSettings() { if (forcedCommand == null && settingsPanel != null) saveCommand(commandField.getText().trim()); } @Override public boolean settingsDirty() { return forcedCommand == null && settingsPanel != null && !commandField.getText().trim().equals(getCommand()); } private void saveCommand(String command) { if (forcedCommand == null) NbPreferences.forModule(ExternalSourcesViewer.class).put(PROP_COMMAND, command); } private String getCommand() { return forcedCommand == null ? NbPreferences.forModule(ExternalSourcesViewer.class).get(PROP_COMMAND, DEFAULT_COMMAND).trim() : forcedCommand; } private static void configureCommand() { ProfilerDialogs.displayWarning(Bundle.ExternalSourcesViewer_NotConfigured(), Bundle.ExternalSourcesViewer_NotConfiguredCaption(), null); OptionsDisplayer.getDefault().open("SourcesOptions"); // NOI18N } private static void executeCommand(SourceHandle handle, String commandS) { List commandL = ExternalViewerLauncher.getCommandStrings(commandS); for (int i = 0; i < commandL.size(); i++) { String commandI = commandL.get(i); if (i == 0) { // first command should be path to viewer executable if ((commandI.startsWith("'") && commandI.endsWith("'")) || // NOI18N (commandI.startsWith("\"") && commandI.endsWith("\""))) { // NOI18N commandI = commandI.substring(1, commandI.length() - 1); commandL.set(i, commandI); } } else { // other commands may be feature wildcards commandI = handle.expandFeatures(commandI); commandL.set(i, commandI); } } new ExternalViewerLauncher(commandL) { @Override protected void failed(IOException e) { ProfilerDialogs.displayError(Bundle.ExternalSourcesViewer_CommandFailed(e.getMessage())); LOGGER.log(Level.INFO, "Opening external sources viewer failed", e); // NOI18N } }.run(); } @Override public JComponent getSettingsComponent() { if (settingsPanel == null) { settingsPanel = new JPanel(null); settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.LINE_AXIS)); settingsPanel.setOpaque(false); int tab = 15; int gap = 5; JLabel parametersCaption = new JLabel(); Mnemonics.setLocalizedText(parametersCaption, Bundle.ExternalSourcesViewer_CommandLabel()); settingsPanel.add(parametersCaption); settingsPanel.add(Box.createHorizontalStrut(gap)); commandField = new JTextField(getCommand()); parametersCaption.setLabelFor(commandField); settingsPanel.add(commandField); settingsPanel.add(Box.createHorizontalStrut(gap)); SmallButton fileChooser = new SmallButton("...") { // NOI18N protected void fireActionPerformed(ActionEvent e) { super.fireActionPerformed(e); JFileChooser fileChooser = new JFileChooser((String)null); fileChooser.setDialogTitle(Bundle.ExternalSourcesViewer_RootsDialogCaption()); fileChooser.setApproveButtonText(Bundle.ExternalSourcesViewer_RootsDialogButton()); fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); if (fileChooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) insertFile(commandField, fileChooser.getSelectedFile()); } }; fileChooser.setToolTipText(Bundle.ExternalSourcesViewer_OpenRootsDialogToolTip()); settingsPanel.add(fileChooser); settingsPanel.add(Box.createHorizontalStrut(gap)); PopupButton parametersPopup = new PopupButton() { protected void populatePopup(JPopupMenu popup) { IdePreset[] ides = IdePreset.sorted(); for (IdePreset ide : ides) { final String command = ide.getCommand(); JMenuItem item = new JMenuItem(ide.getName()) { protected void fireActionPerformed(ActionEvent e) { super.fireActionPerformed(e); commandField.setText(command); } }; popup.add(item); } popup.addSeparator(); ToolPreset[] tools = ToolPreset.sorted(); for (ToolPreset tool : tools) { final String command = tool.getCommand(); JMenuItem item = new JMenuItem(tool.getName()) { protected void fireActionPerformed(ActionEvent e) { super.fireActionPerformed(e); commandField.setText(command); } }; popup.add(item); } popup.addSeparator(); SourceHandle.Feature[] features = SourceHandle.Feature.values(); int longestCode = 0; for (SourceHandle.Feature feature : features) longestCode = Math.max(longestCode, feature.getCode().length()); for (SourceHandle.Feature feature : features) { final String parameter = feature.getCode(); String val = "" + appendSpaces(parameter, longestCode) + "  " + feature.getName() + ""; // NOI18N JMenuItem item = new JMenuItem(val) { protected void fireActionPerformed(ActionEvent e) { super.fireActionPerformed(e); insertParameter(commandField, parameter); } }; popup.add(item); } } }; parametersPopup.setToolTipText(Bundle.ExternalSourcesViewer_InsertCommandToolTip()); parametersPopup.setPopupAlign(SwingConstants.NORTH); settingsPanel.add(parametersPopup); Dimension dim = parametersPopup.getPreferredSize(); fileChooser.setPreferredSize(dim); fileChooser.setMinimumSize(dim); fileChooser.setMaximumSize(dim); if (forcedCommand != null) { commandField.setEditable(false); fileChooser.setEnabled(false); parametersPopup.setEnabled(false); } } return settingsPanel; } private static String appendSpaces(String string, int targetLength) { int spacesToAdd = targetLength - string.length(); for (int i = 0; i < spacesToAdd; i++) string += " "; // NOI18N return string; } private static void insertFile(JTextField textField, File file) { String path = file.getAbsolutePath(); if (path.contains(" ")) path = "\"" + path + "\""; // NOI18N // try { textField.getDocument().insertString(textField.getCaretPosition(), path, null); } try { textField.getDocument().insertString(0, path, null); textField.select(0, path.length()); textField.requestFocusInWindow(); } catch (BadLocationException ex) {} } private static void insertParameter(JTextField textField, String parameter) { Document document = textField.getDocument(); int length = document.getLength(); int position = textField.getCaretPosition(); try { if (position > 0 && !" ".equals(document.getText(position - 1, 1))) // NOI18N parameter = " " + parameter; // NOI18N if (position < length - 1 && !" ".equals(document.getText(position, 1))) // NOI18N parameter = parameter + " "; // NOI18N textField.getDocument().insertString(position, parameter, null); } catch (BadLocationException ex) {} } } ================================================ FILE: visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/ExternalViewerLauncher.java ================================================ /* * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.gotosource.viewer; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.graalvm.visualvm.core.datasource.Storage; /** * @author Jiri Sedlacek */ class ExternalViewerLauncher implements Runnable { private static final String COMMAND_STRINGS_REGEX = "\'[^\']*\'|\"[^\"]*\"|\\S+"; // NOI18N private final List command; ExternalViewerLauncher(List command) { this.command = command; } public final void run() { ProcessBuilder builder = new ProcessBuilder(); builder.command(command); builder.directory(Storage.getTemporaryStorageDirectory()); try { builder.start(); } catch (IOException e) { failed(e); } } protected void failed(IOException e) {} public static List getCommandStrings(String commandString) { List command = new ArrayList<>(); Pattern pattern = Pattern.compile(COMMAND_STRINGS_REGEX); Matcher matcher = pattern.matcher(commandString); while (matcher.find()) command.add(matcher.group()); return command; } } ================================================ FILE: visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/RegisteredSourcesViewer.java ================================================ /* * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.gotosource.viewer; import org.graalvm.visualvm.gotosource.SourcesViewer; import java.awt.Desktop; import java.io.File; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs; import org.graalvm.visualvm.gotosource.SourceHandle; import org.openide.awt.Mnemonics; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; import org.openide.util.lookup.ServiceProvider; /** * * @author Jiri Sedlacek */ @NbBundle.Messages({ "RegisteredSourcesViewer_Name=Registered Viewer", // NOI18N "RegisteredSourcesViewer_Description=viewer registered in the operating system", // NOI18N "# {0} - error message", "RegisteredSourcesViewer_CommandFailed=Failed to open source in registered viewer.\n\n{0}", // NOI18N "RegisteredSourcesViewer_ModeLabel=Mode:", // NOI18N "RegisteredSourcesViewer_OpenChoice=O&pen", // NOI18N "RegisteredSourcesViewer_EditChoice=&Edit" // NOI18N }) @ServiceProvider(service=SourcesViewer.class, position = 200) public final class RegisteredSourcesViewer extends SourcesViewer { private static final Logger LOGGER = Logger.getLogger(RegisteredSourcesViewer.class.getName()); private static final String ID = "RegisteredSourcesViewer"; // NOI18N private static final String PROP_MODE = "prop_RegisteredSourcesViewer_mode"; // NOI18N private static final boolean DEFAULT_MODE = Boolean.FALSE; private JPanel settingsPanel; private JRadioButton openChoice; private JRadioButton editChoice; public RegisteredSourcesViewer() { super(ID, Bundle.RegisteredSourcesViewer_Name(), Bundle.RegisteredSourcesViewer_Description()); } @Override public boolean open(SourceHandle handle) { try { if (isEdit()) Desktop.getDesktop().edit(new File(handle.getSourceFile())); else Desktop.getDesktop().open(new File(handle.getSourceFile())); } catch (IOException ex) { ProfilerDialogs.displayError(Bundle.RegisteredSourcesViewer_CommandFailed(ex.getMessage())); LOGGER.log(Level.INFO, "Failed to open source " + handle.getSourceFile(), ex); // NOI18N } return true; } @Override public void loadSettings() { if (settingsPanel != null) { boolean edit = isEdit(); openChoice.setSelected(!edit); editChoice.setSelected(edit); } } @Override public void saveSettings() { if (settingsPanel != null) saveEdit(editChoice.isSelected()); } @Override public boolean settingsDirty() { return settingsPanel != null && isEdit() != editChoice.isSelected(); } private void saveEdit(boolean edit) { NbPreferences.forModule(RegisteredSourcesViewer.class).putBoolean(PROP_MODE, edit); } private boolean isEdit() { return NbPreferences.forModule(RegisteredSourcesViewer.class).getBoolean(PROP_MODE, DEFAULT_MODE); } @Override public JComponent getSettingsComponent() { if (settingsPanel == null) { settingsPanel = new JPanel(null); settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.LINE_AXIS)); settingsPanel.setOpaque(false); int tab = 15; int gap = 5; JLabel modeCaption = new JLabel(); Mnemonics.setLocalizedText(modeCaption, Bundle.RegisteredSourcesViewer_ModeLabel()); settingsPanel.add(modeCaption); settingsPanel.add(Box.createHorizontalStrut(gap)); openChoice = new JRadioButton(); Mnemonics.setLocalizedText(openChoice, Bundle.RegisteredSourcesViewer_OpenChoice()); settingsPanel.add(openChoice); settingsPanel.add(Box.createHorizontalStrut(gap)); editChoice = new JRadioButton(); Mnemonics.setLocalizedText(editChoice, Bundle.RegisteredSourcesViewer_EditChoice()); settingsPanel.add(editChoice); ButtonGroup bg = new ButtonGroup(); bg.add(openChoice); bg.add(editChoice); boolean edit = isEdit(); openChoice.setSelected(!edit); editChoice.setSelected(edit); } return settingsPanel; } } ================================================ FILE: visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/internal/InternalSourceAppearance.java ================================================ /* * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.gotosource.viewer.internal; import java.awt.Dimension; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.prefs.Preferences; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.JTextArea; import javax.swing.SpinnerNumberModel; import javax.swing.text.DefaultFormatter; import org.openide.awt.Mnemonics; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; /** * * @author Jiri Sedlacek */ @NbBundle.Messages({ "InternalSourceAppearance_FontPlain=Plain", // NOI18N "InternalSourceAppearance_FontBold=Bold", // NOI18N "InternalSourceAppearance_FontItalic=Italic", // NOI18N "InternalSourceAppearance_FontBoldItalic=Bold Italic", // NOI18N "InternalSourceAppearance_FontLabel=&Font:", // NOI18N "InternalSourceAppearance_StyleLabel=S&tyle:", // NOI18N "InternalSourceAppearance_SizeLabel=S&ize:" // NOI18N }) final class InternalSourceAppearance { private static final String PROP_FONT_NAME = "prop_InternalSourceAppearance_fontName"; // NOI18N private static final String PROP_FONT_STYLE = "prop_InternalSourceAppearance_fontStyle"; // NOI18N private static final String PROP_FONT_SIZE = "prop_InternalSourceAppearance_fontSize"; // NOI18N private static final int DEFAULT_FONT_STYLE = Font.PLAIN; private static final int DEFAULT_FONT_SIZE = new JTextArea().getFont().getSize(); private static final String DEFAULT_FONT_NAME = new Font(Font.MONOSPACED, DEFAULT_FONT_STYLE, DEFAULT_FONT_SIZE).getName(); private static enum FontStyle { PLAIN(Font.PLAIN, Bundle.InternalSourceAppearance_FontPlain()), BOLD(Font.BOLD, Bundle.InternalSourceAppearance_FontBold()), ITALIC(Font.ITALIC, Bundle.InternalSourceAppearance_FontItalic()), BOLD_ITALIC(Font.BOLD | Font.ITALIC, Bundle.InternalSourceAppearance_FontBoldItalic()); private final int style; private final String name; FontStyle(int style, String name) { this.style = style; this.name = name; } int getStyle() { return style; } String getName() { return name; } @Override public String toString() { return getName(); } static FontStyle fromStyle(int style) { switch (style) { case Font.PLAIN: return PLAIN; case Font.BOLD: return BOLD; case Font.ITALIC: return ITALIC; default: return BOLD_ITALIC; } } } private final PropertyChangeSupport changeSupport; private JPanel settingsPanel; InternalSourceAppearance() { changeSupport = new PropertyChangeSupport(this); } Font getFont() { Preferences preferences = NbPreferences.forModule(InternalSourceAppearance.class); return new Font(savedFontName(preferences), savedFontStyle(preferences), savedFontSize(preferences)); } void addListener(PropertyChangeListener listener) { changeSupport.addPropertyChangeListener(listener); } void removeListener(PropertyChangeListener listener) { changeSupport.removePropertyChangeListener(listener); } void loadSettings() { if (settingsPanel == null) return; Preferences settings = NbPreferences.forModule(InternalSourceAppearance.class); fontSelect.setSelectedItem(savedFontName(settings)); styleSelect.setSelectedItem(FontStyle.fromStyle(savedFontStyle(settings))); sizeSelect.setValue(Integer.valueOf(savedFontSize(settings))); } void saveSettings() { if (settingsPanel == null || !currentSettingsDirty()) return; Preferences settings = NbPreferences.forModule(InternalSourceAppearance.class); settings.put(PROP_FONT_NAME, currentFontName()); settings.putInt(PROP_FONT_STYLE, currentFontStyle()); settings.putInt(PROP_FONT_SIZE, currentFontSize()); changeSupport.firePropertyChange(new PropertyChangeEvent(this, "appearance", null, null)); // NOI18N } boolean currentSettingsDirty() { if (settingsPanel == null) return false; Preferences settings = NbPreferences.forModule(InternalSourceAppearance.class); if (!currentFontName().equals(savedFontName(settings))) return true; if (currentFontStyle() != savedFontStyle(settings)) return true; if (currentFontSize() != savedFontSize(settings)) return true; return false; } private String savedFontName(Preferences preferences) { return preferences.get(PROP_FONT_NAME, DEFAULT_FONT_NAME).trim(); } private String currentFontName() { return fontSelect.getEditor().getItem().toString().trim(); } private int savedFontStyle(Preferences preferences) { return preferences.getInt(PROP_FONT_STYLE, DEFAULT_FONT_STYLE); } private int currentFontStyle() { return ((FontStyle)styleSelect.getSelectedItem()).getStyle(); } private int savedFontSize(Preferences preferences) { return preferences.getInt(PROP_FONT_SIZE, DEFAULT_FONT_SIZE); } private int currentFontSize() { try { return Integer.parseInt(((JSpinner.DefaultEditor)sizeSelect.getEditor()).getTextField().getText().trim()); } catch (Exception e) { return ((Integer)sizeSelect.getValue()).intValue(); } } JComponent getSettingsComponent() { if (settingsPanel == null) { settingsPanel = new JPanel(null); settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.LINE_AXIS)); settingsPanel.setOpaque(false); int tab = 15; int gap = 5; JLabel fontCaption = new JLabel(); Mnemonics.setLocalizedText(fontCaption, Bundle.InternalSourceAppearance_FontLabel()); settingsPanel.add(fontCaption); settingsPanel.add(Box.createHorizontalStrut(gap)); fontSelect = new JComboBox<>(getAvailableFonts(false)); fontSelect.setSelectedItem(new Font(Font.MONOSPACED, Font.PLAIN, 12).getName()); Dimension dim = fontSelect.getMinimumSize(); dim.width = 20; fontSelect.setMinimumSize(dim); fontSelect.setMaximumSize(fontSelect.getPreferredSize()); fontSelect.setEditable(true); fontCaption.setLabelFor(fontSelect); settingsPanel.add(fontSelect); settingsPanel.add(Box.createHorizontalStrut(tab)); JLabel styleCaption = new JLabel(); Mnemonics.setLocalizedText(styleCaption, Bundle.InternalSourceAppearance_StyleLabel()); settingsPanel.add(styleCaption); settingsPanel.add(Box.createHorizontalStrut(gap)); styleSelect = new JComboBox<>(FontStyle.values()); styleSelect.setPreferredSize(styleSelect.getMinimumSize()); styleSelect.setMaximumSize(styleSelect.getMinimumSize()); styleCaption.setLabelFor(styleSelect); settingsPanel.add(styleSelect); settingsPanel.add(Box.createHorizontalStrut(tab)); JLabel sizeCaption = new JLabel(); Mnemonics.setLocalizedText(sizeCaption, Bundle.InternalSourceAppearance_SizeLabel()); settingsPanel.add(sizeCaption); settingsPanel.add(Box.createHorizontalStrut(gap)); sizeSelect = new JSpinner(new SpinnerNumberModel(sizeCaption.getFont().getSize(), 1, 99, 1)); try { JFormattedTextField editor = ((JSpinner.DefaultEditor)sizeSelect.getEditor()).getTextField(); ((DefaultFormatter)editor.getFormatter()).setAllowsInvalid(false); } catch (Exception e) {} sizeSelect.setPreferredSize(sizeSelect.getMinimumSize()); sizeSelect.setMaximumSize(sizeSelect.getMinimumSize()); sizeCaption.setLabelFor(sizeSelect); settingsPanel.add(sizeSelect); loadSettings(); } return settingsPanel; } private static String[] getAvailableFonts(boolean monospaced) { return GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); } private JComboBox fontSelect; private JComboBox styleSelect; private JSpinner sizeSelect; } ================================================ FILE: visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/internal/InternalSourceViewerComponent.java ================================================ /* * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.gotosource.viewer.internal; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Shape; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.BorderFactory; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.JViewport; import javax.swing.SwingUtilities; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableModel; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultHighlighter; import javax.swing.text.JTextComponent; import javax.swing.text.View; import org.openide.util.Exceptions; /** * * @author Jiri Sedlacek */ final class InternalSourceViewerComponent extends JPanel implements PropertyChangeListener { private InternalSourceAppearance appearance; private final SourceArea sourceArea; private final LineNumbers lineNumbers; private final JViewport lineNumbersViewport; private final JPanel lineNumbersPanel; public InternalSourceViewerComponent(String text, int offset, int endOffset, InternalSourceAppearance appearance) { super(new BorderLayout()); sourceArea = new SourceArea(); this.appearance = appearance; appearance.addListener(this); propertyChange(null); sourceArea.setText(text); setOffset(offset, endOffset); lineNumbersPanel = new JPanel(new BorderLayout()); lineNumbersPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 10)); lineNumbers = new LineNumbers(sourceArea); lineNumbersPanel.add(lineNumbers, BorderLayout.EAST); lineNumbersViewport = new JViewport(); lineNumbersViewport.setView(lineNumbersPanel); lineNumbersViewport.setPreferredSize(lineNumbersPanel.getPreferredSize()); JScrollPane scrollPane = new JScrollPane(sourceArea); scrollPane.setBorder(BorderFactory.createEmptyBorder()); scrollPane.setViewportBorder(BorderFactory.createEmptyBorder()); scrollPane.setRowHeader(lineNumbersViewport); add(scrollPane, BorderLayout.CENTER); } @Override public void propertyChange(PropertyChangeEvent evt) { sourceArea.setFont(appearance.getFont()); if (lineNumbers != null) { lineNumbers.updateAppearance(sourceArea); lineNumbersViewport.setPreferredSize(lineNumbersPanel.getPreferredSize()); validate(); repaint(); } } void setOffset(final int offset, final int endOffset) { sourceArea.setOffset(offset); SwingUtilities.invokeLater(new Runnable() { public void run() { sourceArea.select(offset, endOffset); } }); } void cleanup() { appearance.removeListener(this); appearance = null; } Component defaultFocusOwner() { return sourceArea; } private static class SourceArea extends JTextArea implements CaretListener { private int pendingOffset = -1; private Object rowHighlight; private final LineHighlightPainter highlightPainter; SourceArea() { super(); setEditable(false); setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 5)); highlightPainter = new LineHighlightPainter(); addCaretListener(this); MouseAdapter adapter = new MouseAdapter() { public void mousePressed(MouseEvent e) { setHighlight(SourceArea.this.getCaret().getDot()); } public void mouseDragged(MouseEvent e) { setHighlight(SourceArea.this.getCaret().getDot()); } }; addMouseListener(adapter); addMouseMotionListener(adapter); } protected int getRowHeight() { return super.getRowHeight(); } void setOffset(int offset) { setCaretPosition(offset); scrollToOffset(offset); } private void scrollToOffset(int offset) { if (isValid()) { try { Rectangle offsetRect = modelToView(offset); if (offsetRect != null) { int rowHeight = getRowHeight(); int currentHeight = getVisibleRect().height; int margin = (currentHeight - rowHeight) / 2; offsetRect.y -= margin; offsetRect.height += (margin * 2); scrollRectToVisible(offsetRect); } } catch (BadLocationException ex) {} } else { pendingOffset = offset; } } public void validate() { super.validate(); if (pendingOffset != -1) { scrollToOffset(pendingOffset); pendingOffset = -1; } } public void requestFocus() { super.requestFocus(); setHighlight(getCaretPosition()); } @Override public void caretUpdate(CaretEvent e) { setHighlight(e.getDot()); } public void setHighlight(final int dot) { SwingUtilities.invokeLater(new Runnable() { public void run() { if (rowHighlight != null) getHighlighter().removeHighlight(rowHighlight); int currentLine = getLineFromOffset(SourceArea.this, dot); int startOffset = getLineStartOffsetForLine(SourceArea.this, currentLine); int endOffset = getLineEndOffsetForLine(SourceArea.this, currentLine); try { rowHighlight = getHighlighter().addHighlight(startOffset, endOffset, highlightPainter); } catch (BadLocationException ex) { Exceptions.printStackTrace(ex); } repaint(); } }); } public int getLineFromOffset(JTextComponent component, int offset) { return component.getDocument().getDefaultRootElement().getElementIndex(offset); } public int getLineStartOffsetForLine(JTextComponent component, int line) { return component.getDocument().getDefaultRootElement().getElement(line).getStartOffset(); } public int getLineEndOffsetForLine(JTextComponent component, int line) { return component.getDocument().getDefaultRootElement().getElement(line).getEndOffset(); } static final class LineHighlightPainter extends DefaultHighlighter.DefaultHighlightPainter { LineHighlightPainter() { super(new Color(233, 239, 248)); } public Shape paintLayer(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c, View view) { try { Rectangle r = c.modelToView(offs0); r.x = 0; r.width = c.getWidth(); g.setColor(getColor()); ((Graphics2D)g).fill(r); return r; } catch (BadLocationException ex) { return null; } } } } private static class LineNumbers extends JTable { private int currentLine; LineNumbers(final SourceArea sourceArea) { super(createModel(sourceArea)); setShowGrid(false); setShowHorizontalLines(false); setShowVerticalLines(false); setOpaque(false); setFocusable(false); setCellSelectionEnabled(false); setRowSelectionAllowed(false); setColumnSelectionAllowed(false); setIntercellSpacing(new Dimension(0, 0)); setBackground(new JPanel().getBackground()); setBorder(BorderFactory.createEmptyBorder()); updateAppearance(sourceArea); DefaultTableCellRenderer renderer = new DefaultTableCellRenderer() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); comp.setEnabled(row == currentLine); return comp; } }; renderer.setHorizontalAlignment(JLabel.TRAILING); renderer.setEnabled(false); setDefaultRenderer(Number.class, renderer); currentLine = sourceArea.getLineFromOffset(sourceArea, sourceArea.getCaret().getDot()); sourceArea.addCaretListener(new CaretListener() { @Override public void caretUpdate(CaretEvent e) { currentLine = sourceArea.getLineFromOffset(sourceArea, e.getDot()); repaint(); } }); MouseAdapter adapter = new MouseAdapter() { public void mousePressed(MouseEvent e) { currentLine = sourceArea.getLineFromOffset(sourceArea, sourceArea.getCaret().getDot()); repaint(); } public void mouseDragged(MouseEvent e) { currentLine = sourceArea.getLineFromOffset(sourceArea, sourceArea.getCaret().getDot()); repaint(); } }; sourceArea.addMouseListener(adapter); sourceArea.addMouseMotionListener(adapter); } void updateAppearance(SourceArea sourceArea) { setRowHeight(sourceArea.getRowHeight()); setFont(sourceArea.getFont()); DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)getDefaultRenderer(Number.class); renderer.setFont(sourceArea.getFont()); renderer.setText(Integer.toString(sourceArea.getLineCount())); Dimension dim = sourceArea.getPreferredSize(); dim.width = renderer.getPreferredSize().width; setPreferredSize(dim); } private static TableModel createModel(SourceArea sourceArea) { final int rowCount = sourceArea.getLineCount(); return new AbstractTableModel() { @Override public int getRowCount() { return rowCount; } @Override public int getColumnCount() { return 1; } @Override public Class getColumnClass(int columnIndex) { return Number.class; } @Override public Object getValueAt(int rowIndex, int columnIndex) { return rowIndex + 1; } }; } } } ================================================ FILE: visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/internal/InternalSourceViewerTopComponent.java ================================================ /* * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.gotosource.viewer.internal; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.KeyboardFocusManager; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import org.graalvm.visualvm.gotosource.SourceHandle; import org.openide.util.HelpCtx; import org.openide.util.ImageUtilities; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; /** * * @author Jiri Sedlacek */ final class InternalSourceViewerTopComponent extends TopComponent { private static final String ICON_PATH = "org/graalvm/visualvm/gotosource/resources/gotosource.png"; // NOI18N private final InternalSourceViewerComponent viewerComponent; static void showSource(String uri, String text, int offset, int endOffset, InternalSourceAppearance appearance) { String file = SourceHandle.simpleUri(uri); InternalSourceViewerTopComponent container = findOpened(file); if (container == null) { container = new InternalSourceViewerTopComponent(file, text, offset, endOffset, appearance); container.open(); } else { container.setOffset(offset, endOffset); } container.requestActive(); } private static InternalSourceViewerTopComponent findOpened(String file) { for (TopComponent opened : WindowManager.getDefault().getRegistry().getOpened()) if (opened instanceof InternalSourceViewerTopComponent && file.equals(opened.getToolTipText())) return (InternalSourceViewerTopComponent)opened; return null; } private InternalSourceViewerTopComponent(String file, String text, int offset, int endOffset, InternalSourceAppearance appearance) { super(); setDisplayName(new File(file).getName()); setIcon(ImageUtilities.loadImage(ICON_PATH, true)); setToolTipText(file); viewerComponent = new InternalSourceViewerComponent(text, offset, endOffset, appearance); setLayout(new BorderLayout()); add(viewerComponent, BorderLayout.CENTER); } private void setOffset(int offset, int endOffset) { viewerComponent.setOffset(offset, endOffset); } protected void componentClosed() { super.componentClosed(); viewerComponent.cleanup(); } public int getPersistenceType() { return PERSISTENCE_NEVER; } protected String preferredID() { return getDisplayName(); } public HelpCtx getHelpCtx() { return null; } private Component lastFocusOwner; private final PropertyChangeListener focusListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { Component c = evt.getNewValue() instanceof Component ? (Component)evt.getNewValue() : null; processFocusedComponent(c); } private void processFocusedComponent(Component c) { Component cc = c; while (c != null) { if (c == InternalSourceViewerTopComponent.this) { lastFocusOwner = cc; return; } c = c.getParent(); } } }; protected void componentActivated() { super.componentActivated(); if (lastFocusOwner != null) { lastFocusOwner.requestFocus(); } else { Component defaultFocusOwner = defaultFocusOwner(); if (defaultFocusOwner != null) defaultFocusOwner.requestFocus(); } KeyboardFocusManager.getCurrentKeyboardFocusManager(). addPropertyChangeListener("focusOwner", focusListener); // NOI18N } protected void componentDeactivated() { KeyboardFocusManager.getCurrentKeyboardFocusManager(). removePropertyChangeListener("focusOwner", focusListener); // NOI18N super.componentDeactivated(); } protected Component defaultFocusOwner() { return viewerComponent.defaultFocusOwner(); } public Dimension getMinimumSize() { return new Dimension(0, 0); } } ================================================ FILE: visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/internal/InternalSourcesViewer.java ================================================ /* * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.gotosource.viewer.internal; import javax.swing.JComponent; import javax.swing.SwingUtilities; import org.graalvm.visualvm.gotosource.SourceHandle; import org.graalvm.visualvm.gotosource.SourcesViewer; import org.openide.util.NbBundle; //import org.openide.util.lookup.ServiceProvider; /** * * @author Jiri Sedlacek */ @NbBundle.Messages({ "InternalSourcesViewer_Name=Internal Viewer", // NOI18N "InternalSourcesViewer_Description=simple built-in text viewer" // NOI18N }) //@ServiceProvider(service=SourcesViewer.class, position = 100) public final class InternalSourcesViewer extends SourcesViewer { private static final String ID = "InternalSourcesViewer"; // NOI18N private InternalSourceAppearance appearance; public InternalSourcesViewer() { super(ID, Bundle.InternalSourcesViewer_Name(), Bundle.InternalSourcesViewer_Description()); } @Override public boolean open(SourceHandle handle) { final String uri = handle.getSourceUri(); final String text = handle.getText(); final int offset = handle.getOffset(); final int endOffset = handle.getEndOffset(); SwingUtilities.invokeLater(new Runnable() { public void run() { InternalSourceViewerTopComponent.showSource(uri, text, offset == -1 ? 0 : offset, offset == -1 ? 0 : endOffset, getAppearance()); } }); return true; } @Override public void loadSettings() { if (appearance != null) appearance.loadSettings(); } @Override public void saveSettings() { if (appearance != null) appearance.saveSettings(); } @Override public boolean settingsDirty() { return appearance != null && appearance.currentSettingsDirty(); } @Override public JComponent getSettingsComponent() { return getAppearance().getSettingsComponent(); } private InternalSourceAppearance getAppearance() { if (appearance == null) appearance = new InternalSourceAppearance(); return appearance; } } ================================================ FILE: visualvm/graalvm/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.graalvm. ================================================ FILE: visualvm/graalvm/manifest.mf ================================================ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: false AutoUpdate-Essential-Module: true OpenIDE-Module: org.graalvm.visualvm.graalvm/2 OpenIDE-Module-Install: org/graalvm/visualvm/graalvm/Installer.class OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/graalvm/Bundle.properties OpenIDE-Module-Specification-Version: 2.0 ================================================ FILE: visualvm/graalvm/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: visualvm/graalvm/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=45d87257 build.xml.script.CRC32=4bbd8550 build.xml.stylesheet.CRC32=a56c6a5b@2.73 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=45d87257 nbproject/build-impl.xml.script.CRC32=5ea5e3c3 nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73 ================================================ FILE: visualvm/graalvm/nbproject/project.properties ================================================ javac.source=1.8 javac.compilerargs=-Xlint -Xlint:-serial license.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io module.javadoc.packages=org.graalvm.visualvm.graalvm.* ================================================ FILE: visualvm/graalvm/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.graalvm org.graalvm.visualvm.application 2 2.3 org.graalvm.visualvm.application.views 2 2.0 org.graalvm.visualvm.charts 2 2.1 org.graalvm.visualvm.core 2 2.0 org.graalvm.visualvm.host 2 2.0 org.graalvm.visualvm.tools 2 2.0 org.openide.modules 7.49 org.openide.util 9.8 org.openide.util.ui 9.8 ================================================ FILE: visualvm/graalvm/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/Bundle.properties ================================================ # # Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Infrastructure OpenIDE-Module-Name=VisualVM-GraalVM Extensions ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/Installer.java ================================================ /* * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm; import org.graalvm.visualvm.application.jvm.JvmFactory; import org.graalvm.visualvm.application.type.ApplicationTypeFactory; import org.graalvm.visualvm.graalvm.application.type.GraalVMApplicationTypeFactory; import org.graalvm.visualvm.graalvm.libgraal.MemorySnapshotViewPluginProvider; import org.graalvm.visualvm.graalvm.libgraal.MemoryViewPluginProvider; import org.graalvm.visualvm.graalvm.svm.SVMJvmProvider; import org.openide.modules.ModuleInstall; public class Installer extends ModuleInstall { @Override public void restored() { ApplicationTypeFactory.getDefault().registerProvider(new GraalVMApplicationTypeFactory()); // NOTE: adds [native image] suffix to native-image processes // DataSourceDescriptorFactory.getDefault().registerProvider(new NativeImageApplicationDescriptorProvider()); JvmFactory.getDefault().registerProvider(new SVMJvmProvider()); MemorySnapshotViewPluginProvider.initialize(); MemoryViewPluginProvider.initialize(); } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/application/descriptor/NativeImageApplicationDescriptor.java ================================================ /* * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.application.descriptor; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.ApplicationDescriptor; /** * * @author Jiri Sedlacek */ class NativeImageApplicationDescriptor extends ApplicationDescriptor { protected NativeImageApplicationDescriptor(Application application) { super(application); } public String getName() { return super.getName() + " [native image]"; } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/application/descriptor/NativeImageApplicationDescriptorProvider.java ================================================ /* * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.application.descriptor; import java.util.Properties; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.application.jvm.JvmFactory; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor; import org.graalvm.visualvm.core.model.AbstractModelProvider; /** * * @author Jiri Sedlacek */ public class NativeImageApplicationDescriptorProvider extends AbstractModelProvider { public DataSourceDescriptor createModelFor(DataSource ds) { if (ds instanceof Application) { Jvm jvm = JvmFactory.getJVMFor((Application)ds); if (jvm.isGetSystemPropertiesSupported()) { Properties prop = jvm.getSystemProperties(); if ("Substrate VM".equals(prop.getProperty("java.vm.name"))) // NOI18N return new NativeImageApplicationDescriptor((Application)ds); } } return null; } public int priority() { return 10; } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/application/type/Bundle.properties ================================================ # # Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. DESCR_GraalVMBasedApplicationType=Graal is a just-in-time compiler for the JVM focused on peak performance and multi-language support. Graal offers performance advantages not only to Java code, but also to scripting languages such as JavaScript, Python, Ruby, and R. LBL_GraalVM=GraalVM DESCR_GraalVM=GraalVM application. LBL_Graalvm_Javascript=JavaScript LBL_Graalvm_R=R LBL_Graalvm_Rscript=Rscript LBL_Graalvm_Ruby=Ruby LBL_Graalvm_Nodejs=Node.js LBL_Graalvm_Python=Python LBL_Graalvm_LLVM=Sulong ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/application/type/GraalVMApplicationType.java ================================================ /* * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.application.type; import java.awt.Image; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.application.type.ApplicationType; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; /** * This {@link ApplicationType} represents application based on GraalVM. * * @author Tomas Hurka */ public class GraalVMApplicationType extends ApplicationType { private Application application; private String name; GraalVMApplicationType(Application app, Jvm jvm, String n) { application = app; name = n; } /** * {@inheritDoc} */ public String getName() { return name; } /** * {@inheritDoc} */ public String getVersion() { return getMessage("LBL_Unknown"); // NOI18N } /** * {@inheritDoc} */ public String getDescription() { return getMessage("DESCR_GraalVMBasedApplicationType"); // NOI18N } /** * {@inheritDoc} */ public Image getIcon() { String iconPath = "org/graalvm/visualvm/graalvm/application/type/GraalVM.png"; // NOI18N return ImageUtilities.loadImage(iconPath, true); } String getMessage(String string) { return NbBundle.getMessage(GraalVMApplicationType.class, string); } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/application/type/GraalVMApplicationTypeFactory.java ================================================ /* * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.application.type; import java.util.Properties; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.application.type.ApplicationType; import org.graalvm.visualvm.application.type.MainClassApplicationTypeFactory; import org.openide.util.NbBundle; /** * Factory which recognizes GraalVM and some applications based on GraalVM * * @author Tomas Hurka */ public class GraalVMApplicationTypeFactory extends MainClassApplicationTypeFactory { private static final String MAIN_CLASS = "com.oracle.graalvm.Main"; // NOI18N private static final String LEGACY_MAIN_CLASS = "com.oracle.graalvm.launcher.LegacyLauncher"; // NOI18N private static final String JAVASCRIPT_MAIN_CLASS = "com.oracle.truffle.js.shell.JSLauncher"; // NOI18N private static final String R_LEGACY_MAIN_CLASS = "com.oracle.truffle.r.legacylauncher.LegacyLauncher"; // NOI18N private static final String R_MAIN_CLASS = "com.oracle.truffle.r.launcher.RMain"; // NOI18N private static final String RUBY_MAIN_CLASS = "org.truffleruby.launcher.RubyLauncher"; // NOI18N private static final String PYTHON_MAIN_CLASS = "com.oracle.graal.python.shell.GraalPythonMain"; // NOI18N private static final String PYTHON_EE_MAIN_CLASS = "com.oracle.graal.python.enterprise.shell.GraalPythonEnterpriseMain"; // NOI18N private static final String LLVM_MAIN_CLASS = "com.oracle.truffle.llvm.launcher.LLVMLauncher"; // NOI18N private static final String GRAAL_SYSPROP_ID = "graalvm.home"; // NOI18N private static final String GRAAL_SYSPROP1_ID = "org.graalvm.home"; // NOI18N private static final String LAUNCHER_SYSPROP_ID = "org.graalvm.launcher.class"; // NOI18N private static final String JVM_ARG_GRAAL_ID = "-D"+GRAAL_SYSPROP_ID+"="; // NOI18N private static final String JVM_ARG_GRAAL1_ID = "-Dgraal.CompilerConfiguration="; // NOI18N private static final String ARG_GRAAL_ID = "--"; // NOI18N private static final String JVM_ARG_NODEJS_ID = "-Dtruffle.js.DirectByteBuffer=true"; // NOI18N private static final String JVM_ARG_NODEJS1_ID = "-Dtruffle.js.DebugPropertyName=GraalJsDebug"; // NOI18N private static final String JAVASCRIPT_ID = "com.oracle.truffle.js.shell.Shell"; // NOI18N private static final String R_ID = "com.oracle.truffle.r.engine.shell.RCommand"; // NOI18N private static final String LEGACY_RSCRIPT_ID = "com.oracle.truffle.r.launcher.RscriptCommand"; // NOI18N private static final String LEGACY_R_ID = "com.oracle.truffle.r.launcher.RCommand"; // NOI18N private static final String RUBY_ID = "org.truffleruby.Main"; // NOI18N; private static final String NODEJS_ID = "node.js"; // NOI18N; private static final String PYTHON_ID = "GraalPythonMain"; // NOI18N private static final String LLVM_ID = "LLVM"; // NOI18N private boolean isGraalVM(Jvm jvm, String mainClass) { if (MAIN_CLASS.equals(mainClass) || LEGACY_MAIN_CLASS.equals(mainClass)) { return true; } if (JAVASCRIPT_MAIN_CLASS.equals(mainClass)) { return true; } if (R_MAIN_CLASS.equals(mainClass)) { return true; } if (R_LEGACY_MAIN_CLASS.equals(mainClass)) { return true; } if (RUBY_MAIN_CLASS.equals(mainClass)) { return true; } if (PYTHON_MAIN_CLASS.equals(mainClass)) { return true; } if (PYTHON_EE_MAIN_CLASS.equals(mainClass)) { return true; } if (LLVM_MAIN_CLASS.equals(mainClass)) { return true; } if (mainClass == null || mainClass.isEmpty()) { // there is no main class - detect native GraalVM launcher String args = jvm.getJvmArgs(); if (args != null) { if (args.contains(JVM_ARG_GRAAL_ID) || args.contains(JVM_ARG_GRAAL1_ID) || args.contains(JVM_ARG_NODEJS_ID)) { return true; } } if (jvm.isGetSystemPropertiesSupported()) { Properties sysProp = jvm.getSystemProperties(); if (sysProp != null) { if (sysProp.getProperty(GRAAL_SYSPROP_ID) != null || sysProp.getProperty(GRAAL_SYSPROP1_ID) != null || sysProp.getProperty(LAUNCHER_SYSPROP_ID) != null) { return true; } } } } return false; } private String getLangID(Jvm jvm) { String args = jvm.getMainArgs(); String mainClass = jvm.getMainClass(); if ((mainClass == null || mainClass.isEmpty()) && jvm.isGetSystemPropertiesSupported()) { Properties sysProp = jvm.getSystemProperties(); if (sysProp != null) { mainClass = sysProp.getProperty(LAUNCHER_SYSPROP_ID); } } if (LEGACY_MAIN_CLASS.equals(mainClass)) { if (args != null) { String[] argArr = args.split(" +"); if (argArr.length > 1) { return argArr[1]; } } } if (JAVASCRIPT_MAIN_CLASS.equals(mainClass)) { return JAVASCRIPT_ID; } if (R_MAIN_CLASS.equals(mainClass)) { return R_ID; } if (R_LEGACY_MAIN_CLASS.equals(mainClass)) { return R_ID; } if (RUBY_MAIN_CLASS.equals(mainClass)) { return RUBY_ID; } if (PYTHON_MAIN_CLASS.equals(mainClass)) { return PYTHON_ID; } if (PYTHON_EE_MAIN_CLASS.equals(mainClass)) { return PYTHON_ID; } if (LLVM_MAIN_CLASS.equals(mainClass)) { return LLVM_ID; } if (args != null) { String[] argArr = args.split(" +"); if (argArr.length > 2) { if (ARG_GRAAL_ID.equals(argArr[1])) { return argArr[2]; } } } return null; } private String getName(String lang) { if (lang == null) { return getMessage("LBL_GraalVM"); } switch (lang) { case JAVASCRIPT_ID: return getMessage("LBL_Graalvm_Javascript"); // NOI18N case R_ID: case LEGACY_R_ID: return getMessage("LBL_Graalvm_R"); // NOI18N case LEGACY_RSCRIPT_ID: return getMessage("LBL_Graalvm_Rscript"); // NOI18N case RUBY_ID: return getMessage("LBL_Graalvm_Ruby"); // NOI18N case NODEJS_ID: return getMessage("LBL_Graalvm_Nodejs"); // NOI18N case PYTHON_ID: return getMessage("LBL_Graalvm_Python"); // NOI18N case LLVM_ID: return getMessage("LBL_Graalvm_LLVM"); // NOI18N default: return lang; } } String getMessage(String string) { return NbBundle.getMessage(GraalVMApplicationTypeFactory.class, string); } @Override public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) { if (isGraalVM(jvm, mainClass)) { String langId = getLangID(jvm); if (langId == null && (mainClass == null || mainClass.isEmpty())) { // nodejs ??? String jvmArgs = jvm.getJvmArgs(); if (jvmArgs.contains(JVM_ARG_NODEJS_ID) || jvmArgs.contains(JVM_ARG_NODEJS1_ID)) { langId = NODEJS_ID; } } String name = getName(langId); return new GraalVMApplicationType(app, jvm, name); } return null; } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/Bundle.properties ================================================ # # Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. # HTML-formatted: (< and > must remain!) LBL_Unknown=<unknown> LBL_Memory=Memory LBL_Heap=Heap LBL_Heap_size=Size LBL_Used_heap=Used LBL_Heap_size_leg={0} size LBL_Used_heap_leg=Used {0} LBL_Max_Heap=Max ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/MemoryModel.java ================================================ /* * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.libgraal; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.lang.management.MemoryUsage; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.Attribute; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.openmbean.CompositeData; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.application.jvm.JvmFactory; import org.graalvm.visualvm.application.jvm.MonitoredData; import org.graalvm.visualvm.application.jvm.MonitoredDataListener; import org.graalvm.visualvm.application.snapshot.ApplicationSnapshot; import org.graalvm.visualvm.charts.SimpleXYChartSupport; import org.graalvm.visualvm.core.VisualVM; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.datasource.Storage; import org.graalvm.visualvm.core.options.GlobalPreferences; import org.graalvm.visualvm.core.snapshot.Snapshot; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; /** * * @author Tomas Hurka */ final class MemoryModel { private static final Logger LOGGER = Logger.getLogger(MemoryModel.class.getName()); private static final String PROP_PREFIX = "LibgraalModel_"; // NOI18N private static final String USAGE_ATTRIBUTE = "Usage"; // NOI18N private static final String PEAK_USAGE_ATTRIBUTE = "PeakUsage"; // NOI18N private static final String SNAPSHOT_VERSION = PROP_PREFIX + "version"; // NOI18N private static final String SNAPSHOT_VERSION_DIVIDER = "."; // NOI18N private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = "1"; // NOI18N private static final String CURRENT_SNAPSHOT_VERSION_MINOR = "0"; // NOI18N private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR; private static final String PROP_NOT_DEFINED = ""; // NOI18N private static final String PROP_CHART_CACHE = PROP_PREFIX + "chart_cache"; // NOI18N private static final String PROP_HEAP_NAME = PROP_PREFIX + "heap_name"; // NOI18N private static final String PROP_HEAP_CAPACITY = PROP_PREFIX + "heap_capacity"; // NOI18N private static final String PROP_HEAP_USED = PROP_PREFIX + "heap_used"; // NOI18N private static final String PROP_MAX_HEAP = PROP_PREFIX + "max_heap"; // NOI18N private static final String CHART_STORAGE = PROP_PREFIX + "monitor_libgraal.dat"; // NOI18N private boolean initialized; private DataSource source; private boolean live; private final List listeners; private SimpleXYChartSupport heapChartSupport; private MonitoredDataListener monitoredDataListener; private Jvm jvm; private ObjectName libgraalName; private MBeanServerConnection connection; private int chartCache = -1; private long timestamp = -1; private String heapName; private long heapCapacity = -1; private long heapUsed = -1; private long maxHeap = -1; static MemoryModel create(Application application, String name, ObjectName libgraalName) { return new MemoryModel(application, name, libgraalName); } static MemoryModel create(DataSource ds, String name) { return new MemoryModel(ds, name); } DataSource getSource() { return source; } boolean isLive() { return live; } long getTimestamp() { return timestamp; } int getChartCache() { return chartCache; } String getHeapName() { return heapName; } long getHeapCapacity() { return heapCapacity; } long getHeapUsed() { return heapUsed; } long getMaxHeap() { return maxHeap; } synchronized void initialize() { if (initialized) { return; } initialized = true; if (source instanceof Application) { initialize((Application) source); } else { initialize((Snapshot) source); } } void registerHeapChartSupport(final SimpleXYChartSupport heapChartSupport) { this.heapChartSupport = heapChartSupport; if (heapChartSupport != null && source instanceof Snapshot) { VisualVM.getInstance().runTask(new Runnable() { public void run() { File file = new File(source.getStorage().getDirectory(), CHART_STORAGE); if (file.isFile() && file.canRead()) { loadChartSupport(heapChartSupport, file); } } }); } } synchronized void cleanup() { listeners.clear(); if (!initialized) { return; } if (jvm != null && monitoredDataListener != null) { jvm.removeMonitoredDataListener(monitoredDataListener); } connection = null; } void addChangeListener(ChangeListener listener) { if (live) { listeners.add(listener); } } void removeChangeListener(ChangeListener listener) { if (live) { listeners.remove(listener); } } void save(Snapshot snapshot) { initialize(); Storage storage = snapshot.getStorage(); setProperty(storage, SNAPSHOT_VERSION, CURRENT_SNAPSHOT_VERSION); setProperty(storage, PROP_CHART_CACHE, Integer.toString(chartCache)); setProperty(storage, PROP_HEAP_NAME, heapName); setProperty(storage, PROP_HEAP_CAPACITY, Long.toString(heapCapacity)); setProperty(storage, PROP_HEAP_USED, Long.toString(heapUsed)); setProperty(storage, PROP_MAX_HEAP, Long.toString(maxHeap)); File dir = storage.getDirectory(); saveChartSupport(heapChartSupport, new File(dir, CHART_STORAGE)); } private static void saveChartSupport(SimpleXYChartSupport chartSupport, File file) { if (chartSupport == null) { return; } try (OutputStream os = new FileOutputStream(file)) { chartSupport.saveValues(os); } catch (Exception e) { LOGGER.log(Level.INFO, "saveChartSupport", e); // NOI18N } } private static void loadChartSupport(SimpleXYChartSupport chartSupport, File file) { try (InputStream is = new FileInputStream(file)) { chartSupport.loadValues(is); } catch (Exception e) { LOGGER.log(Level.INFO, "loadChartSupport", e); // NOI18N } } private void initialize(Snapshot snapshot) { // TODO: if some property cannot be loaded for current snapshot version, FAIL initializing the snapshot! Storage storage = snapshot.getStorage(); String version = getProperty(storage, SNAPSHOT_VERSION); heapName = getProperty(storage, PROP_HEAP_NAME); chartCache = Integer.parseInt(getProperty(storage, PROP_CHART_CACHE)); heapCapacity = Long.parseLong(getProperty(storage, PROP_HEAP_CAPACITY)); heapUsed = Long.parseLong(getProperty(storage, PROP_HEAP_USED)); maxHeap = Long.parseLong(getProperty(storage, PROP_MAX_HEAP)); } private static void setProperty(Storage storage, String property, String value) { storage.setCustomProperty(property, value == null ? PROP_NOT_DEFINED : value); } private static String getProperty(Storage storage, String property) { String value = storage.getCustomProperty(property); return PROP_NOT_DEFINED.equals(value) ? null : value; } private void initialize(Application application) { GlobalPreferences preferences = GlobalPreferences.sharedInstance(); chartCache = preferences.getMonitoredDataCache() * 60 / preferences.getMonitoredDataPoll(); jvm = JvmFactory.getJVMFor(application); connection = getConnection(application); if (connection != null) { updateValues(System.currentTimeMillis(), getData()); if (live) { monitoredDataListener = new MonitoredDataListener() { long lastTimestamp = -1; public void monitoredDataEvent(final MonitoredData data) { long timestamp = System.currentTimeMillis(); final long timestampF = lastTimestamp < timestamp ? lastTimestamp = timestamp : ++lastTimestamp; final Object[] values = getData(); SwingUtilities.invokeLater(new Runnable() { public void run() { updateValues(timestampF, values); fireChange(); } }); } }; jvm.addMonitoredDataListener(monitoredDataListener); } } } private Object[] getAttributes(String... names) { try { List attrs = connection.getAttributes(libgraalName, names).asList(); Object[] values = new Object[attrs.size()]; for (int i = 0; i < values.length; i++) { values[i] = attrs.get(i).getValue(); } return values; } catch (Exception ex) { LOGGER.log(Level.INFO, "getAttributes", ex); // NOI18N } return null; } private Object[] getData() { if (live && connection != null) { Object[] values = getAttributes(USAGE_ATTRIBUTE, PEAK_USAGE_ATTRIBUTE); if (values == null) { connection = null; } return values; } return null; } private void updateValues(final long time, Object[] values) { if (values != null) { CompositeData usageData = (CompositeData) values[0]; CompositeData peakData = (CompositeData) values[1]; if (usageData != null && peakData != null) { MemoryUsage mem = MemoryUsage.from(usageData); MemoryUsage peak = MemoryUsage.from(peakData); heapUsed = mem.getUsed(); heapCapacity = peak.getUsed(); maxHeap = mem.getMax(); timestamp = time; } } } private void fireChange() { final List list = new ArrayList<>(); synchronized (listeners) { list.addAll(listeners); } for (ChangeListener l : list) { l.stateChanged(new ChangeEvent(this)); } } private MemoryModel() { initialized = false; listeners = Collections.synchronizedList(new ArrayList<>()); } private MemoryModel(DataSource src, String name) { this(); source = src; heapName = name; live = false; } private MemoryModel(DataSource src, String name, ObjectName mbeanName) { this(src, name); live = true; libgraalName = mbeanName; } private static MBeanServerConnection getConnection(Application app) { JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app); if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) { return jmxModel.getMBeanServerConnection(); } return null; } static boolean isInStapshot(ApplicationSnapshot snapshot) { String version = getProperty(snapshot.getStorage(), SNAPSHOT_VERSION); return version != null; } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/MemorySnapshotViewPluginProvider.java ================================================ /* * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.libgraal; import org.graalvm.visualvm.application.snapshot.ApplicationSnapshot; import org.graalvm.visualvm.application.views.ApplicationViewsSupport; import org.graalvm.visualvm.core.ui.DataSourceViewPlugin; import org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider; /** * * @author Tomas Hurka */ public class MemorySnapshotViewPluginProvider extends DataSourceViewPluginProvider { protected DataSourceViewPlugin createPlugin(ApplicationSnapshot snapshot) { return new MemoryViewPlugin(snapshot, MemoryModel.create(snapshot, MemoryViewPluginProvider.LIBGRAAL_HEAP)); } protected boolean supportsPluginFor(ApplicationSnapshot snapshot) { return MemoryModel.isInStapshot(snapshot); } private MemorySnapshotViewPluginProvider() { } public static void initialize() { ApplicationViewsSupport.sharedInstance().getSnapshotMonitorView(). registerPluginProvider(new MemorySnapshotViewPluginProvider()); } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/MemoryViewComponent.java ================================================ /* * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.libgraal; import java.awt.BorderLayout; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.graalvm.visualvm.charts.ChartFactory; import org.graalvm.visualvm.charts.SimpleXYChartDescriptor; import org.graalvm.visualvm.charts.SimpleXYChartSupport; import org.graalvm.visualvm.core.ui.components.DataViewComponent; import org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer; import org.openide.util.NbBundle; /** * * @author Tomas Hurka */ class MemoryViewComponent extends JPanel { private static final String UNKNOWN = NbBundle.getMessage(MemoryViewComponent.class, "LBL_Unknown"); // NOI18N private boolean liveModel; private boolean memoryMonitoringSupported; private String heapName; private SimpleXYChartSupport chartSupport; MemoryViewComponent(MemoryModel model) { initModels(model); initComponents(); refresh(model); } DataViewComponent.DetailsView getDetailsView() { return new DataViewComponent.DetailsView(heapName, null, 10, this, null); } private void refresh(MemoryModel model) { if (memoryMonitoringSupported) { long heapCapacity = model.getHeapCapacity(); long heapUsed = model.getHeapUsed(); long maxHeap = model.getMaxHeap(); if (liveModel) { chartSupport.addValues(model.getTimestamp(), new long[]{heapCapacity, heapUsed}); } chartSupport.updateDetails(new String[]{chartSupport.formatBytes(heapCapacity), chartSupport.formatBytes(heapUsed), chartSupport.formatBytes(maxHeap)}); } } private void initModels(final MemoryModel model) { liveModel = model.isLive(); memoryMonitoringSupported = true; heapName = memoryMonitoringSupported ? model.getHeapName() : NbBundle.getMessage(MemoryViewComponent.class, "LBL_Memory"); // NOI18N if (memoryMonitoringSupported) { String HEAP_SIZE = NbBundle.getMessage(MemoryViewComponent.class, "LBL_Heap_size"); // NOI18N String HEAP_SIZE_LEG = NbBundle.getMessage(MemoryViewComponent.class, "LBL_Heap_size_leg", heapName); // NOI18N String USED_HEAP = NbBundle.getMessage(MemoryViewComponent.class, "LBL_Used_heap"); // NOI18N String USED_HEAP_LEG = NbBundle.getMessage(MemoryViewComponent.class, "LBL_Used_heap_leg", heapName.toLowerCase()); // NOI18N String MAX_HEAP = NbBundle.getMessage(MemoryViewComponent.class, "LBL_Max_Heap"); // NOI18N SimpleXYChartDescriptor chartDescriptor = SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, model.getChartCache()); chartDescriptor.addLineFillItems(HEAP_SIZE_LEG, USED_HEAP_LEG); chartDescriptor.setDetailsItems(new String[]{HEAP_SIZE, USED_HEAP, MAX_HEAP}); chartDescriptor.setLimitYValue(model.getMaxHeap()); chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor); model.registerHeapChartSupport(chartSupport); chartSupport.setZoomingEnabled(!liveModel); model.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { refresh(model); } }); } } private void initComponents() { setLayout(new BorderLayout()); setOpaque(false); if (memoryMonitoringSupported) { add(chartSupport.getChart(), BorderLayout.CENTER); chartSupport.updateDetails(new String[]{UNKNOWN, UNKNOWN, UNKNOWN}); } else { add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM), BorderLayout.CENTER); } } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/MemoryViewPlugin.java ================================================ /* * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.libgraal; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.ui.DataSourceViewPlugin; import org.graalvm.visualvm.core.ui.components.DataViewComponent; /** * * @author Tomas Hurka */ public class MemoryViewPlugin extends DataSourceViewPlugin { private final MemoryModel model; private MemoryViewComponent view; @Override public DataViewComponent.DetailsView createView(int location) { switch (location) { case DataViewComponent.TOP_RIGHT: view = new MemoryViewComponent(model); return view.getDetailsView(); default: return null; } } protected void willBeAdded() { model.initialize(); } @Override protected void removed() { model.cleanup(); } MemoryModel getModel() { return model; } MemoryViewPlugin(DataSource dataSource, MemoryModel model) { super(dataSource); this.model = model; } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/MemoryViewPluginProvider.java ================================================ /* * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.libgraal; import java.io.IOException; import java.lang.management.ManagementFactory; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.snapshot.ApplicationSnapshot; import org.graalvm.visualvm.application.views.ApplicationViewsSupport; import org.graalvm.visualvm.core.snapshot.Snapshot; import org.graalvm.visualvm.core.ui.DataSourceViewPlugin; import org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; /** * * @author Tomas Hurka */ public class MemoryViewPluginProvider extends DataSourceViewPluginProvider { static final String LIBGRAAL_HEAP = "Libgraal"; // NOI18N private final ObjectName libgraalName; @Override protected DataSourceViewPlugin createPlugin(Application application) { return new MemoryViewPlugin(application, MemoryModel.create(application, LIBGRAAL_HEAP, libgraalName)); } @Override protected boolean supportsPluginFor(Application t) { return isSupported(t); } @Override protected boolean supportsSavePluginFor(Application application, Class snapshotClass) { return ApplicationSnapshot.class.isAssignableFrom(snapshotClass); } @Override protected void savePlugin(Application application, Snapshot snapshot) { MemoryViewPlugin view = (MemoryViewPlugin) getCachedPlugin(application); if (view != null) { view.getModel().save(snapshot); } else { MemoryModel.create(application, LIBGRAAL_HEAP).save(snapshot); } } private MemoryViewPluginProvider() { libgraalName = getLibgraalName(); } public static void initialize() { ApplicationViewsSupport.sharedInstance().getMonitorView(). registerPluginProvider(new MemoryViewPluginProvider()); } private static ObjectName getLibgraalName() { try { return new ObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + ",name=" + LIBGRAAL_HEAP); } catch (MalformedObjectNameException ex) { throw new RuntimeException(ex); } } private static MBeanServerConnection getConnection(Application app) { JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app); if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) { return jmxModel.getMBeanServerConnection(); } return null; } private boolean isSupported(Application app) { try { MBeanServerConnection conn = getConnection(app); if (conn != null) { return conn.isRegistered(libgraalName); } } catch (IOException ex) { } return false; } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/svm/SVMJVMImpl.java ================================================ /* * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.svm; import java.io.File; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardWatchEventKinds; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.Set; import java.util.concurrent.TimeUnit; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.HeapHistogram; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.application.jvm.MonitoredData; import org.graalvm.visualvm.application.jvm.MonitoredDataListener; import org.graalvm.visualvm.core.datasupport.Stateful; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory; import org.graalvm.visualvm.tools.jvmstat.JvmstatListener; import org.graalvm.visualvm.tools.jvmstat.JvmstatModel; import org.graalvm.visualvm.tools.jvmstat.MonitoredValue; /** * * @author Tomas Hurka */ public class SVMJVMImpl extends Jvm implements JvmstatListener { private static final String USER_DIR_COUNTER_NAME = "java.property.user.dir"; private static final String PROCESSORS_COUNTER_NAME = "com.oracle.svm.processors"; private static final String SVM_HEAP_DUMP_PREFIX = "svm-heapdump-"; private static final String SVM_HEAP_DUMP_SUFFIX = ".hprof"; private static final String SYSTEM_PROPERTY_PREFIX = "java.property."; private static final String SYSTEM_PROPERTY_REG_EXPR = SYSTEM_PROPERTY_PREFIX.replace(".", "\\.")+".*"; // NOI18N private static final String MEMORY_COUNTER_REG_EXPR = "sun\\.gc\\.generation\\..*"; Application application; JvmstatModel monitoredVm; JvmJvmstatModel jvmstatModel; Set listeners; // static JVM data private boolean staticDataInitialized; private final Object staticDataLock = new Object(); private String commandLine; private String jvmArgs; private String jvmFlags; private String mainArgs; private String mainClass; private String vmVersion; private String javaVersion; private String javaHome; private String vmInfo; private String vmName; private String vmVendor; SVMJVMImpl(Application app,JvmstatModel jvms) { application = app; monitoredVm = jvms; jvmstatModel = JvmJvmstatModelFactory.getJvmstatModelFor(app); listeners = new HashSet<>(); } public boolean isAttachable() { return false; } public boolean isBasicInfoSupported() { return true; } public String getCommandLine() { initStaticData(); return commandLine; } public String getJvmArgs() { initStaticData(); return jvmArgs; } public String getJvmFlags() { initStaticData(); return jvmFlags; } public String getMainArgs() { initStaticData(); return mainArgs; } public String getMainClass() { initStaticData(); return mainClass; } public String getVmVersion() { initStaticData(); return vmVersion; } public String getJavaVersion() { initStaticData(); if (javaVersion != null) { return javaVersion; } return vmVersion; } public String getJavaHome() { initStaticData(); return javaHome; } public String getVmInfo() { initStaticData(); return vmInfo; } public String getVmName() { initStaticData(); return vmName; } public String getVmVendor() { initStaticData(); return vmVendor; } public boolean is14() { return false; } public boolean is15() { return false; } public boolean is16() { return false; } public boolean is17() { return false; } public boolean is18() { String ver = getJavaVersion(); if (ver != null && ver.startsWith("1.8.")) { return true; } return false; } public boolean is19() { String ver = getJavaVersion(); if (ver != null && javaVersion != null && (ver.startsWith("1.9.") || (ver.equals("9")) || (ver.startsWith("9.")))) { // NOI18N return true; } return false; } public boolean is100() { String ver = getJavaVersion(); if (ver != null && javaVersion != null && (ver.equals("10") || ver.startsWith("10."))) { // NOI18N return true; } return false; } public boolean is110() { String ver = getJavaVersion(); if (ver != null && javaVersion != null && (ver.equals("11") || ver.equals("11-ea") || ver.startsWith("11."))) { // NOI18N return true; } return false; } public boolean isDumpOnOOMEnabled() { return false; } public void addMonitoredDataListener(MonitoredDataListener l) { synchronized (listeners) { if (listeners.add(l)) { if (monitoredVm != null) { monitoredVm.addJvmstatListener(this); } } } } public void removeMonitoredDataListener(MonitoredDataListener l) { synchronized (listeners) { if (listeners.remove(l)) { if (listeners.isEmpty()) { if (monitoredVm != null) { monitoredVm.removeJvmstatListener(this); } } } } } public String[] getGenName() { if (jvmstatModel != null) { return jvmstatModel.getGenName(); } throw new UnsupportedOperationException(); } public boolean isMonitoringSupported() { return isClassMonitoringSupported() || isThreadMonitoringSupported() || isMemoryMonitoringSupported(); } public boolean isClassMonitoringSupported() { return monitoredVm != null; } public boolean isThreadMonitoringSupported() { return monitoredVm != null; } public boolean isMemoryMonitoringSupported() { if (monitoredVm != null) { List vals = monitoredVm.findByPattern(MEMORY_COUNTER_REG_EXPR); return vals != null && !vals.isEmpty(); } return false; } public boolean isGetSystemPropertiesSupported() { return true; } @Override public int getAvailableProcessors() { MonitoredValue procs = monitoredVm.findMonitoredValueByName(PROCESSORS_COUNTER_NAME); if (procs != null) { return ((Long)procs.getValue()).intValue(); } // default return 1; } public Properties getSystemProperties() { Properties p = new Properties(); for (MonitoredValue val : monitoredVm.findMonitoredValueByPattern(SYSTEM_PROPERTY_REG_EXPR)) { p.put(val.getName().substring(SYSTEM_PROPERTY_PREFIX.length()), val.getValue()); } return p; } public boolean isDumpOnOOMEnabledSupported() { return false; } public synchronized void setDumpOnOOMEnabled(boolean enabled) { } public boolean isTakeHeapDumpSupported() { if (application.isLocalApplication()) { return monitoredVm.findByName(USER_DIR_COUNTER_NAME) != null; } return false; } public boolean takeHeapDump(File outputFile) throws IOException { if (!isTakeHeapDumpSupported()) { throw new UnsupportedOperationException(); } String cwd = monitoredVm.findByName(USER_DIR_COUNTER_NAME); Path applicationCwd = Paths.get(cwd); WatchService watchService = FileSystems.getDefault().newWatchService(); WatchKey key = applicationCwd.register(watchService, StandardWatchEventKinds.ENTRY_CREATE); Runtime.getRuntime().exec(new String[] {"kill", "-USR1", String.valueOf(application.getPid())}); try { Path name = findHeapDumpFile(key); if (name == null) { key = watchService.poll(20, TimeUnit.SECONDS); name = findHeapDumpFile(key); } watchService.close(); if (name == null) { return false; } Path dumpPath = applicationCwd.resolve(name); Path outputPath = outputFile.toPath(); waitDumpDone(dumpPath); Files.move(dumpPath, outputPath); return true; } catch (InterruptedException ex) { watchService.close(); return false; } } private Path findHeapDumpFile(WatchKey key) { for (WatchEvent event : key.pollEvents()) { WatchEvent.Kind kind = event.kind(); if (kind == StandardWatchEventKinds.OVERFLOW) { continue; } WatchEvent ev = (WatchEvent)event; Path filename = ev.context(); String name = filename.toString(); if (name.endsWith(SVM_HEAP_DUMP_SUFFIX) && name.startsWith(SVM_HEAP_DUMP_PREFIX)) { return filename; } } return null; } public boolean isTakeThreadDumpSupported() { return false; } public String takeThreadDump() { throw new UnsupportedOperationException(); } public HeapHistogram takeHeapHistogram() { return null; } public boolean isCpuMonitoringSupported() { return true; } public boolean isCollectionTimeSupported() { return false; } public boolean isJfrAvailable() { return false; } public List jfrCheck() { return Collections.emptyList(); } public String takeJfrDump(long recording, String fileName) { throw new UnsupportedOperationException(); } public boolean startJfrRecording(String name, String[] settings, String delay, String duration, Boolean disk, String path, String maxAge, String maxSize, Boolean dumpOnExit) { throw new UnsupportedOperationException(); } public boolean stopJfrRecording() { throw new UnsupportedOperationException(); } public MonitoredData getMonitoredData() { if (application.getState() == Stateful.STATE_AVAILABLE) { if (monitoredVm != null) { return new SVMMonitoredDataImpl(this, monitoredVm, jvmstatModel); } } return null; } protected void initStaticData() { synchronized (staticDataLock) { if (staticDataInitialized) { return; } if (jvmstatModel != null) { commandLine = jvmstatModel.getCommandLine(); jvmArgs = jvmstatModel.getJvmArgs(); jvmFlags = jvmstatModel.getJvmFlags(); mainArgs = jvmstatModel.getMainArgs(); mainClass = jvmstatModel.getMainClass(); vmVersion = jvmstatModel.getVmVersion(); javaVersion = jvmstatModel.getJavaVersion(); javaHome = jvmstatModel.getJavaHome(); vmInfo = jvmstatModel.getVmInfo(); vmName = jvmstatModel.getVmName(); vmVendor = jvmstatModel.getVmVendor(); } staticDataInitialized = true; } } public void dataChanged(JvmstatModel stat) { assert stat == monitoredVm; MonitoredData data = new SVMMonitoredDataImpl(this, monitoredVm, jvmstatModel); notifyListeners(data); } void notifyListeners(final MonitoredData data) { List listenersCopy; synchronized (listeners) { listenersCopy = new ArrayList<>(listeners); } for (MonitoredDataListener listener : listenersCopy) { listener.monitoredDataEvent(data); } } private void waitDumpDone(Path name) throws IOException { long size; long newSize = Files.size(name); do { size = newSize; try { Thread.sleep(1000); } catch (InterruptedException ex) { return; } newSize = Files.size(name); } while (size != newSize); } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/svm/SVMJvmProvider.java ================================================ /* * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.svm; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.core.model.AbstractModelProvider; import org.graalvm.visualvm.tools.jvmstat.JvmstatModel; import org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory; /** * * @author Tomas Hurka */ public class SVMJvmProvider extends AbstractModelProvider { private static final String SVM_VM_NAME = "Substrate VM"; // NOI18N private static final String VM_NAME = "java.property.java.vm.name"; // NOI18N @Override public int priority() { return 10; } @Override public Jvm createModelFor(Application app) { Jvm jvm = null; JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app); if (jvmstat != null) { String vmName = jvmstat.findByName(VM_NAME); if (SVM_VM_NAME.equals(vmName)) { jvm = new SVMJVMImpl(app, jvmstat); } } return jvm; } } ================================================ FILE: visualvm/graalvm/src/org/graalvm/visualvm/graalvm/svm/SVMMonitoredDataImpl.java ================================================ /* * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.graalvm.svm; import org.graalvm.visualvm.application.jvm.Jvm; import org.graalvm.visualvm.application.jvm.MonitoredData; import org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel; import org.graalvm.visualvm.tools.jvmstat.JvmstatModel; import org.graalvm.visualvm.tools.jvmstat.MonitoredValue; /** * * @author Tomas Hurka */ public class SVMMonitoredDataImpl extends MonitoredData { private static final String ProcessCPUTime_COUNTER_NAME = "com.oracle.svm.processCPUTime"; // NOI18N SVMMonitoredDataImpl(Jvm jvm, JvmstatModel monitoredVm, JvmJvmstatModel jvmstatModel) { this.monitoredVm = jvm; loadedClasses = jvmstatModel.getLoadedClasses(); sharedLoadedClasses = jvmstatModel.getSharedLoadedClasses(); sharedUnloadedClasses = jvmstatModel.getSharedUnloadedClasses(); unloadedClasses = jvmstatModel.getUnloadedClasses(); threadsDaemon = jvmstatModel.getThreadsDaemon(); threadsLive = jvmstatModel.getThreadsLive(); threadsLivePeak = jvmstatModel.getThreadsLivePeak(); threadsStarted = jvmstatModel.getThreadsStarted(); applicationTime = jvmstatModel.getApplicationTime()/(jvmstatModel.getOsFrequency()/1000); upTime = jvmstatModel.getUpTime()/(jvmstatModel.getOsFrequency()/1000); genCapacity = jvmstatModel.getGenCapacity(); genUsed = jvmstatModel.getGenUsed(); genMaxCapacity = jvmstatModel.getGenMaxCapacity(); MonitoredValue cpuTimeVal = monitoredVm.findMonitoredValueByName(ProcessCPUTime_COUNTER_NAME); if (cpuTimeVal != null) { processCpuTime = ((Long)cpuTimeVal.getValue()).longValue(); } } } ================================================ FILE: visualvm/heapdump/build.xml ================================================ Builds, tests, and runs the project org.graalvm.visualvm.heapdump. ================================================ FILE: visualvm/heapdump/manifest.mf ================================================ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: false AutoUpdate-Essential-Module: true OpenIDE-Module: org.graalvm.visualvm.heapdump/2 OpenIDE-Module-Install: org/graalvm/visualvm/heapdump/Installer.class OpenIDE-Module-Layer: org/graalvm/visualvm/heapdump/resources/layer.xml OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/heapdump/Bundle.properties OpenIDE-Module-Specification-Version: 2.1 ================================================ FILE: visualvm/heapdump/nbproject/build-impl.xml ================================================ You must set 'suite.dir' to point to your containing module suite ================================================ FILE: visualvm/heapdump/nbproject/genfiles.properties ================================================ build.xml.data.CRC32=5428a1b3 build.xml.script.CRC32=c00ae7ac build.xml.stylesheet.CRC32=a56c6a5b@2.73 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=5428a1b3 nbproject/build-impl.xml.script.CRC32=f1cff99d nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73 ================================================ FILE: visualvm/heapdump/nbproject/project.properties ================================================ javac.compilerargs=-Xlint -Xlint:-serial javac.source=1.8 license.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt nbm.homepage=https://visualvm.github.io ================================================ FILE: visualvm/heapdump/nbproject/project.xml ================================================ org.netbeans.modules.apisupport.project org.graalvm.visualvm.heapdump org.graalvm.visualvm.application 2 2.3 org.graalvm.visualvm.core 2 2.2 org.graalvm.visualvm.coredump 2 2.0 org.graalvm.visualvm.heapviewer 2 2.2 org.graalvm.visualvm.lib.jfluid 2 2.0 org.graalvm.visualvm.lib.profiler 2 2.0 org.graalvm.visualvm.lib.profiler.heapwalker 2 2.0 org.graalvm.visualvm.tools 2 2.0 org.netbeans.api.progress 1 1.48 org.netbeans.modules.sendopts 2 2.43 org.openide.awt 7.23.1 org.openide.dialogs 7.13.1 org.openide.filesystems 9.11 org.openide.modules 7.3.1 org.openide.util 8.6.1 org.openide.util.lookup 8.34 org.openide.util.ui 9.8 org.openide.windows 6.18.1 org.graalvm.visualvm.heapdump ================================================ FILE: visualvm/heapdump/nbproject/suite.properties ================================================ suite.dir=${basedir}/.. ================================================ FILE: visualvm/heapdump/src/org/graalvm/visualvm/heapdump/Bundle.properties ================================================ # # Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. OpenIDE-Module-Display-Category=Infrastructure OpenIDE-Module-Name=VisualVM-HeapDump LBL_Save_Heap_Dump_As=Save Heap Dump As DESCR_HeapDump=Heap dump. ================================================ FILE: visualvm/heapdump/src/org/graalvm/visualvm/heapdump/HeapDump.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.heapdump; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.snapshot.Snapshot; import org.graalvm.visualvm.core.snapshot.SnapshotsSupport; import java.io.File; import org.graalvm.visualvm.core.datasupport.Utils; import org.openide.util.NbBundle; /** * Abstract implementation of HeapDump. * Each heapdump is defined by a heapdump file. * * @author Jiri Sedlacek */ public abstract class HeapDump extends Snapshot { private static final String HWCACHE_EXT = ".hwcache"; // NOI18N /** * Creates new instance of HeapDump with the data stored in a file. * * @param file file where heap dump is saved. */ public HeapDump(File file) { this(file, null); } /** * Creates new instance of HeapDump with the data stored in a file and defined master. * * @param file file where heap dump is saved, * @param master DataSource in whose window the heap dump will be displayed. */ public HeapDump(File file, DataSource master) { super(file, HeapDumpSupport.getInstance().getCategory(), master); } public boolean supportsSaveAs() { return getFile() != null; } public void saveAs() { SnapshotsSupport.getInstance().saveAs(this, NbBundle.getMessage(HeapDump.class, "LBL_Save_Heap_Dump_As")); // NOI18N } protected void remove() { final File f = getFile(); // #GH-111: delete the corresponding .hwcache directory if (f != null) Utils.FILE_QUEUE.post(new Runnable() { public void run() { File ff = new File(f.getParent(), f.getName() + HWCACHE_EXT); if (ff.isDirectory()) Utils.delete(ff, true); } }); super.remove(); } } ================================================ FILE: visualvm/heapdump/src/org/graalvm/visualvm/heapdump/HeapDumpDescriptor.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.heapdump; import org.graalvm.visualvm.core.snapshot.SnapshotDescriptor; import org.graalvm.visualvm.core.snapshot.SnapshotsSupport; import java.awt.Image; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; /** * DataSourceDescriptor for HeapDump. * * @author Jiri Sedlacek */ public class HeapDumpDescriptor extends SnapshotDescriptor { private static final Image ICON = SnapshotsSupport.getInstance().createSnapshotIcon( ImageUtilities.loadImage("org/graalvm/visualvm/heapdump/resources/heapdumpBase.png", true)); // NOI18N /** * Creates new instance of HeapDumpDescriptor. * * @param heapDump HeapDump for the descriptor. */ public HeapDumpDescriptor(HeapDump heapDump) { super(heapDump, NbBundle.getMessage(HeapDumpDescriptor.class, "DESCR_HeapDump"), ICON); // NOI18N } } ================================================ FILE: visualvm/heapdump/src/org/graalvm/visualvm/heapdump/HeapDumpSupport.java ================================================ /* * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.heapdump; import org.graalvm.visualvm.heapdump.impl.HeapDumpDescriptorProvider; import org.graalvm.visualvm.heapdump.impl.HeapDumpCategory; import org.graalvm.visualvm.heapdump.impl.HeapDumpViewProvider; import org.graalvm.visualvm.heapdump.impl.HeapDumpProvider; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.jvm.JvmFactory; import org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory; import org.graalvm.visualvm.core.datasupport.Stateful; import org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories; import org.graalvm.visualvm.core.snapshot.SnapshotCategory; import org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider; import org.graalvm.visualvm.coredump.CoreDump; import org.graalvm.visualvm.tools.jmx.JmxModel; import org.graalvm.visualvm.tools.jmx.JmxModelFactory; /** * Support for heap dumps in VisualVM. * * @author Jiri Sedlacek */ public final class HeapDumpSupport { private static HeapDumpSupport instance; private final SnapshotCategory category = new HeapDumpCategory(); private final HeapDumpProvider heapDumpProvider; private final HeapDumpViewProvider heapDumpViewProvider; /** * Returns singleton instance of HeapDumpSupport. * * @return singleton instance of HeapDumpSupport. */ public static synchronized HeapDumpSupport getInstance() { if (instance == null) instance = new HeapDumpSupport(); return instance; } /** * Returns SnapshotCategory instance for heap dumps. * * @return SnapshotCategory instance for heap dumps. */ public SnapshotCategory getCategory() { return category; } /** * Returns true if taking heap dumps is supported for the application, false otherwise. * * @param application application from which to take the heap dump. * @return true if taking heap dumps is supported for the application, false otherwise. */ public boolean supportsHeapDump(Application application) { if (application.getState() != Stateful.STATE_AVAILABLE) return false; return JvmFactory.getJVMFor(application).isTakeHeapDumpSupported(); } /** * Takes heap dump from Application. * * @param application Application to take the heap dump, * @param openView true if taken heap dump should be opened, false otherwise. */ public void takeHeapDump(Application application, boolean openView) { heapDumpProvider.createHeapDump(application, openView); } /** * Returns true if taking heap dumps is supported for the remote application. * * @param application remote application from which to take the heap dump * @return true if taking heap dumps is supported for the remote application, false otherwise */ public boolean supportsRemoteHeapDump(Application application) { if (application.getState() != Stateful.STATE_AVAILABLE) return false; if (application.isLocalApplication()) return false; // Should be allowed??? JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application); return jmxModel != null && jmxModel.isTakeHeapDumpSupported(); } /** * Takes heap dump from remote Application. * * @param application remote Application to take the heap dump * @param dumpFile target dump file on the remote machine * @param customizeDumpFile true if the dumpFile customization dialog should be displayed, false otherwise */ public void takeRemoteHeapDump(Application application, String dumpFile, boolean customizeDumpFile) { heapDumpProvider.createRemoteHeapDump(application, dumpFile, customizeDumpFile); } /** * Takes heap dump from CoreDump. * * @param coreDump CoreDump to take the heap dump, * @param openView true if taken heap dump should be opened, false otherwise. */ public void takeHeapDump(CoreDump coreDump, boolean openView) { heapDumpProvider.createHeapDump(coreDump, openView); } /** * Returns PluggableDataSourceViewProvider for heap dumps. * * @return PluggableDataSourceViewProvider for heap dumps. */ public PluggableDataSourceViewProvider getHeapDumpView() { return heapDumpViewProvider; } private HeapDumpSupport() { DataSourceDescriptorFactory.getDefault().registerProvider(new HeapDumpDescriptorProvider()); heapDumpProvider = new HeapDumpProvider(); heapDumpProvider.initialize(); heapDumpViewProvider = new HeapDumpViewProvider(); RegisteredSnapshotCategories.sharedInstance().registerCategory(category); heapDumpViewProvider.initialize(); } } ================================================ FILE: visualvm/heapdump/src/org/graalvm/visualvm/heapdump/Installer.java ================================================ /* * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.heapdump; import org.openide.modules.ModuleInstall; /** * Manages a module's lifecycle. Remember that an installer is optional and * often not needed at all. */ final class Installer extends ModuleInstall { public void restored() { HeapDumpSupport.getInstance(); } } ================================================ FILE: visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/Bundle.properties ================================================ # # Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. Oracle designates this # particular file as subject to the "Classpath" exception as provided # by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. MSG_Heap_Dump=&Heap Dump LBL_Heap_Dump=Heap Dump LBL_Heap_Dumps=Heap Dumps LBL_Heap_Dump_on_OOME=Heap Dump on &OOME DESCR_Heap_Dump_on_OOME=Control whether to dump heap when an OOME occurs #LBL_Disable_Heap_Dump_on_OOME=&Disable Heap Dump on OOME #DESCR_Disable_Heap_Dump_on_OOME=Disable Heap Dump on OOME #LBL_Enable_Heap_Dump_on_OOME=&Enable Heap Dump on OOME #DESCR_Enable_Heap_Dump_on_OOME=Enable Heap Dump on OOME MSG_Cannot_take_heap_dump=Cannot take heap dump for LBL_Creating_Heap_Dump=Creating Heap Dump... LBL_Loading_Heap_Dump=Loading heap dump... LBL_Loading_Heap_Dump_failed=Loading Heap Dump failed. LBL_Loading_Heap_Dump_failed2=Loading failed: {0} MSG_Opening_Heap_Dump=Opening Heap Dump... MSG_Opening_Heap_Dump_failed=Opening heap dump failed. CAPTION_Remote_heap_dump=Remote Heap Dump MSG_Remote_heap_dump=&Heap dump file to be created on the remote system\: MSG_Dump_failed=Failed to take remote heap dump for this application. MSG_Dump_save_failed=Failed to create remote heap dump and save it\:\n{0} MSG_Dump_ok=Heap dump has been created and saved on the remote system:\n{0}\n\nMove the file to the local system and use File | Load... action to open it. Argument_ShortDescr=take heap dump of the provided process MSG_NO_APP_PID = Cannot find application with pid {0}. ================================================ FILE: visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpAction.java ================================================ /* * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.heapdump.impl; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.coredump.CoreDump; import org.graalvm.visualvm.core.datasource.DataSource; import org.graalvm.visualvm.core.datasupport.Stateful; import org.graalvm.visualvm.core.ui.actions.ActionUtils; import org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction; import org.graalvm.visualvm.heapdump.HeapDumpSupport; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.HashSet; import java.util.Set; import org.openide.util.NbBundle; /** * * @author Jiri Sedlacek */ class HeapDumpAction extends MultiDataSourceAction { private Set lastSelectedApplications = new HashSet<>(); private final PropertyChangeListener stateListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { updateState(ActionUtils.getSelectedDataSources()); } }; private static HeapDumpAction INSTANCE; public static synchronized HeapDumpAction instance() { if (INSTANCE == null) INSTANCE = new HeapDumpAction(); return INSTANCE; } protected void actionPerformed(Set dataSources, ActionEvent actionEvent) { HeapDumpSupport support = HeapDumpSupport.getInstance(); for (DataSource dataSource : dataSources) { if (dataSource instanceof Application) { Application application = (Application)dataSource; boolean tagged = (actionEvent.getModifiers() & Toolkit. getDefaultToolkit().getMenuShortcutKeyMask()) != 0; if (application.isLocalApplication()) { support.takeHeapDump(application, !tagged); } else { support.takeRemoteHeapDump(application, null, !tagged); } } else if (dataSource instanceof CoreDump) { CoreDump coreDump = (CoreDump)dataSource; support.takeHeapDump(coreDump, (actionEvent.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0); } } } protected boolean isEnabled(Set dataSources) { HeapDumpSupport support = HeapDumpSupport.getInstance(); for (DataSource dataSource : dataSources) if (dataSource instanceof Application) { // TODO: Listener should only be registered when heap dump is supported for the application Application application = (Application)dataSource; lastSelectedApplications.add(application); application.addPropertyChangeListener(Stateful.PROPERTY_STATE, stateListener); if (application.getState() != Stateful.STATE_AVAILABLE) return false; if (application.isLocalApplication()) { if (!support.supportsHeapDump(application)) return false; } else { if (!support.supportsRemoteHeapDump(application)) return false; } } else if (!(dataSource instanceof CoreDump)) return false; return true; } protected void updateState(Set dataSources) { if (!lastSelectedApplications.isEmpty()) for (Application application : lastSelectedApplications) application.removePropertyChangeListener(Stateful.PROPERTY_STATE, stateListener); lastSelectedApplications.clear(); super.updateState(dataSources); } private HeapDumpAction() { super(DataSource.class); putValue(NAME, NbBundle.getMessage(HeapDumpAction.class, "MSG_Heap_Dump")); // NOI18N putValue(SHORT_DESCRIPTION, NbBundle.getMessage(HeapDumpAction.class, "LBL_Heap_Dump")); // NOI18N } } ================================================ FILE: visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpArgument.java ================================================ /* * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.visualvm.heapdump.impl; import java.util.Collections; import java.util.Map; import java.util.Set; import org.graalvm.visualvm.application.Application; import org.graalvm.visualvm.application.ApplicationFinder; import org.graalvm.visualvm.heapdump.HeapDumpSupport; import org.netbeans.api.sendopts.CommandException; import org.netbeans.spi.sendopts.Env; import org.netbeans.spi.sendopts.Option; import org.netbeans.spi.sendopts.OptionProcessor; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; /** * * @author Jiri Sedlacek */ @ServiceProvider(service=OptionProcessor.class) public final class HeapDumpArgument extends OptionProcessor { private static final String LONG_NAME = "heapdump"; // NOI18N private static final Option ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, LONG_NAME), "org.graalvm.visualvm.heapdump.impl.Bundle", "Argument_ShortDescr"); // NOI18N @Override protected Set